Performance follow-ups
This commit is contained in:
+14
-5
@@ -23,14 +23,13 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
|
||||
}) => {
|
||||
const variant = variantProp;
|
||||
const sizing = sizingProp;
|
||||
// Get article-specific background image from frontmatter
|
||||
const getBackgroundImage = (
|
||||
post: ContentThumbnailTemplateProps["post"],
|
||||
variant: "vertical" | "horizontal",
|
||||
orientation: "vertical" | "horizontal",
|
||||
): string => {
|
||||
if (post.frontmatter?.thumbnail) {
|
||||
const imageName =
|
||||
variant === "vertical"
|
||||
orientation === "vertical"
|
||||
? post.frontmatter.thumbnail.vertical
|
||||
: post.frontmatter.thumbnail.horizontal;
|
||||
|
||||
@@ -47,12 +46,21 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
|
||||
? slug
|
||||
: contentCatalogSlugForFallback(slug);
|
||||
|
||||
return variant === "vertical"
|
||||
return orientation === "vertical"
|
||||
? contentBlogVerticalPath(resolvedSlug)
|
||||
: contentBlogHorizontalPath(resolvedSlug);
|
||||
};
|
||||
|
||||
const backgroundImage = getBackgroundImage(post, variant);
|
||||
// For "responsive", emit both orientations so the <picture> source can
|
||||
// swap at smd without a second card in the DOM.
|
||||
const backgroundImage =
|
||||
variant === "responsive"
|
||||
? getBackgroundImage(post, "horizontal")
|
||||
: getBackgroundImage(post, variant);
|
||||
const backgroundImageSmd =
|
||||
variant === "responsive"
|
||||
? getBackgroundImage(post, "vertical")
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<ContentThumbnailTemplateView
|
||||
@@ -61,6 +69,7 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
|
||||
variant={variant}
|
||||
sizing={sizing}
|
||||
backgroundImage={backgroundImage}
|
||||
backgroundImageSmd={backgroundImageSmd}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import type { BlogPost } from "../../../../lib/content";
|
||||
|
||||
export type ContentThumbnailTemplateVariantValue = "vertical" | "horizontal";
|
||||
export type ContentThumbnailTemplateVariantValue =
|
||||
| "vertical"
|
||||
| "horizontal"
|
||||
| "responsive";
|
||||
|
||||
export type ContentThumbnailTemplateSizingValue = "fluid" | "fixed";
|
||||
|
||||
@@ -8,7 +11,8 @@ export interface ContentThumbnailTemplateProps {
|
||||
post: BlogPost;
|
||||
className?: string;
|
||||
/**
|
||||
* Content thumbnail variant.
|
||||
* vertical | horizontal — single layout. responsive — horizontal at <smd,
|
||||
* vertical at ≥smd (Learn grid); single card, viewport-swapped via <picture>.
|
||||
*/
|
||||
variant?: ContentThumbnailTemplateVariantValue;
|
||||
/**
|
||||
@@ -21,7 +25,9 @@ export interface ContentThumbnailTemplateProps {
|
||||
export interface ContentThumbnailTemplateViewProps {
|
||||
post: BlogPost;
|
||||
className: string;
|
||||
variant: "vertical" | "horizontal";
|
||||
variant: ContentThumbnailTemplateVariantValue;
|
||||
sizing: ContentThumbnailTemplateSizingValue;
|
||||
backgroundImage: string;
|
||||
/** Wide-viewport image source for variant="responsive" (≥smd). */
|
||||
backgroundImageSmd?: string;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,41 @@ function ContentThumbnailTemplateView({
|
||||
variant,
|
||||
sizing,
|
||||
backgroundImage,
|
||||
backgroundImageSmd,
|
||||
}: ContentThumbnailTemplateViewProps) {
|
||||
if (variant === "responsive") {
|
||||
// Single card; <picture> swaps the orientation-specific image at smd
|
||||
// (530px), aspect-ratio and content positioning switch via Tailwind.
|
||||
return (
|
||||
<Link
|
||||
href={`/blog/${post.slug}`}
|
||||
className={`group block w-full transition-transform duration-200 hover:scale-[1.02] ${className}`}
|
||||
>
|
||||
<div className="relative aspect-[320/225.5] w-full overflow-hidden smd:aspect-[260/390]">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<picture>
|
||||
{backgroundImageSmd ? (
|
||||
<source
|
||||
media="(min-width: 530px)"
|
||||
srcSet={backgroundImageSmd}
|
||||
/>
|
||||
) : null}
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={backgroundImage}
|
||||
alt=""
|
||||
className="pointer-events-none size-full object-cover"
|
||||
/>
|
||||
</picture>
|
||||
</div>
|
||||
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] smd:left-[6.923%] smd:top-[4.615%] smd:w-[76.923%]">
|
||||
<ContentContainer post={post} size="xs" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === "vertical") {
|
||||
if (sizing === "fixed") {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user