diff options
Diffstat (limited to 'src/components/blog/ListItem.astro')
| -rw-r--r-- | src/components/blog/ListItem.astro | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/components/blog/ListItem.astro b/src/components/blog/ListItem.astro new file mode 100644 index 0000000..6a416d6 --- /dev/null +++ b/src/components/blog/ListItem.astro @@ -0,0 +1,120 @@ +--- +import type { ImageMetadata } from 'astro'; +import { Icon } from 'astro-icon/components'; +import Image from '~/components/common/Image.astro'; +import PostTags from '~/components/blog/Tags.astro'; + +import { APP_BLOG } from 'astrowind:config'; +import type { Post } from '~/types'; + +import { getPermalink } from '~/utils/permalinks'; +import { findImage } from '~/utils/images'; +import { getFormattedDate } from '~/utils/utils'; + +export interface Props { + post: Post; +} + +const { post } = Astro.props; +const image = (await findImage(post.image)) as ImageMetadata | undefined; + +const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') : ''; +--- + +<article + class={`max-w-md mx-auto md:max-w-none grid gap-6 md:gap-8 intersect-once intersect-quarter motion-safe:md:opacity-0 motion-safe:md:intersect:animate-fade ${image ? 'md:grid-cols-2' : ''}`} +> + { + image && + (link ? ( + <a class="relative block group" href={link ?? 'javascript:void(0)'}> + <div class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-72 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg"> + {image && ( + <Image + src={image} + class="absolute inset-0 object-cover w-full h-full mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700" + widths={[400, 900]} + width={900} + sizes="(max-width: 900px) 400px, 900px" + alt={post.title} + aspectRatio="16:9" + loading="lazy" + decoding="async" + /> + )} + </div> + </a> + ) : ( + <div class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-72 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg"> + {image && ( + <Image + src={image} + class="absolute inset-0 object-cover w-full h-full mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700" + widths={[400, 900]} + width={900} + sizes="(max-width: 900px) 400px, 900px" + alt={post.title} + aspectRatio="16:9" + loading="lazy" + decoding="async" + /> + )} + </div> + )) + } + <div class="mt-2"> + <header> + <div class="mb-1"> + <span class="text-sm"> + <Icon name="tabler:clock" class="w-3.5 h-3.5 inline-block -mt-0.5 dark:text-gray-400" /> + <time datetime={String(post.publishDate)} class="inline-block">{getFormattedDate(post.publishDate)}</time> + { + post.author && ( + <> + {' '} + · <Icon name="tabler:user" class="w-3.5 h-3.5 inline-block -mt-0.5 dark:text-gray-400" /> + <span>{post.author.replaceAll('-', ' ')}</span> + </> + ) + } + { + post.category && ( + <> + {' '} + ·{' '} + <a class="hover:underline" href={getPermalink(post.category.slug, 'category')}> + {post.category.title} + </a> + </> + ) + } + </span> + </div> + <h2 class="text-xl sm:text-2xl font-bold leading-tight mb-2 font-heading dark:text-slate-300"> + { + link ? ( + <a + class="inline-block hover:text-primary dark:hover:text-blue-700 transition ease-in duration-200" + href={link} + > + {post.title} + </a> + ) : ( + post.title + ) + } + </h2> + </header> + + {post.excerpt && <p class="flex-grow text-muted dark:text-slate-400 text-lg">{post.excerpt}</p>} + { + post.tags && Array.isArray(post.tags) ? ( + <footer class="mt-5"> + <PostTags tags={post.tags} /> + </footer> + ) : ( + <Fragment /> + ) + } + </div> +</article> |
