Files
vue-journal-layer/app/components/Journal/PostCard.vue
Jakub Zych 1080a3f0c4 feat: WebP and srcset for featured images
- JournalFeaturedImage renders <picture> from featured_images[].variants:
  a WebP source and the original format as srcset fallback, the
  original's width and height, alt; lazy in cards, eager with
  fetchpriority high on the post page; unchanged without variants
- app/utils/srcset.ts (imageSrcsets) with node tests
- acme fixtures and SSR expectations for both cases
2026-11-04 17:10:30 +01:00

32 lines
1.7 KiB
Vue

<script setup lang="ts">
// One post in a listing: image, title link, date and excerpt (UI-SPEC L5).
// The title link is the card's only anchor (D-80): the image is not a link
// and there is no separate "read more" link; the whole card is clickable
// through a CSS stretched link on the title (journal-base.css), with the
// focus ring on the card. Post links carry no rel. headingLevel is 2 in a
// listing and 3 under the related posts' own h2 (D-52).
import type { JournalPost } from '../../utils/types.ts'
import { formatJournalDate } from '../../utils/view.ts'
const props = withDefaults(defineProps<{ post: JournalPost; headingLevel?: 2 | 3 }>(), { headingLevel: 2 })
const { localeProperties } = useI18n()
const links = useJournalLinks()
const href = computed(() => links.postLink(props.post.slug))
const date = computed(() => formatJournalDate(props.post.published_at, localeProperties.value.language ?? 'en'))
const heading = computed(() => (props.headingLevel === 3 ? 'h3' : 'h2'))
</script>
<template>
<article class="journal-post-card">
<div v-if="post.featured_image_url" class="journal-post-card__image">
<JournalFeaturedImage :src="post.featured_image_url" :image="post.featured_images?.[0]" :alt="post.title" sizes="(min-width: 48rem) 33vw, 100vw" />
</div>
<component :is="heading" class="journal-post-card__title">
<NuxtLink v-if="href" :to="href">{{ post.title }}</NuxtLink>
<template v-else>{{ post.title }}</template>
</component>
<time v-if="date" class="journal-post-card__date" :datetime="post.published_at ?? undefined">{{ date }}</time>
<p v-if="post.excerpt" class="journal-post-card__excerpt">{{ post.excerpt }}</p>
</article>
</template>