schmelczer-dev/src/components/ArticleList.astro
2026-05-26 08:28:37 +01:00

62 lines
1.9 KiB
Text

---
import type { CollectionEntry } from 'astro:content';
import EntryThumbnail from './EntryThumbnail.astro';
import TagList from './TagList.astro';
import { ARTICLE_THUMBNAIL, articlePath, formatDate, formatDateShort } from '../lib/site';
interface Props {
posts: CollectionEntry<'posts'>[];
showYear?: boolean;
tagLimit?: number;
timeline?: boolean;
// Opt-in: eagerly load thumbnails that are reliably above the fold. Lists
// below substantial content (related, about, 404) should leave this at zero.
eagerFirstThumbnail?: boolean;
eagerThumbnailCount?: number;
}
const {
posts,
showYear = true,
tagLimit = 3,
timeline = false,
eagerFirstThumbnail = false,
eagerThumbnailCount = eagerFirstThumbnail ? 1 : 0,
} = Astro.props;
---
<ol class:list={['article-list', timeline && 'article-list--timeline']}>
{
posts.map((post, index) => {
const href = articlePath(post);
const eager = index < eagerThumbnailCount;
return (
<li>
<article>
<h3>
<a class="entry-title" href={href}>
{post.data.title}
</a>
</h3>
<p>{post.data.description}</p>
<TagList tags={post.data.tags} limit={tagLimit} />
</article>
<time datetime={post.data.date.toISOString()}>
{showYear ? formatDate(post.data.date) : formatDateShort(post.data.date)}
</time>
<EntryThumbnail
src={post.data.thumbnail.src}
alt={post.data.thumbnail.alt}
href={href}
class="article-thumbnail"
widths={ARTICLE_THUMBNAIL.widths}
sizes={ARTICLE_THUMBNAIL.sizes}
ariaLabel={`Open article: ${post.data.title}`}
loading={eager ? 'eager' : 'lazy'}
fetchpriority={eager && index === 0 ? 'high' : undefined}
/>
</li>
);
})
}
</ol>