62 lines
1.9 KiB
Text
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>
|