Repository navigation
Expand file tree
/
Copy pathCoverImage.astro
More file actions
78 lines (71 loc) · 1.92 KB
/
Copy pathCoverImage.astro
File metadata and controls
78 lines (71 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
---
import { stegaClean } from "@sanity/client/stega";
import type { SanityImageSource } from "@sanity/image-url";
interface Props {
image?: (SanityImageSource & { alt?: string }) | null;
fallbackAlt?: string;
width?: number;
height?: number;
quality?: number;
sizes?: string;
/** Above-the-fold images opt out of lazy loading. */
priority?: boolean;
class?: string;
}
const {
image,
fallbackAlt = "CodingCat.dev tutorial cover image",
width = 1920,
height = 1080,
quality = 82,
sizes = "(max-width: 768px) 100vw, (max-width: 1280px) 50vw, 960px",
priority = false,
class: className = "w-full h-auto aspect-video rounded-md",
} = Astro.props;
const builder = Astro.locals.sanity.urlForImage(image ?? undefined);
const aspect = height / width;
const src = builder
?.width(width)
.height(height)
.quality(quality)
.url();
const responsiveWidths = [320, 480, 640, 960, 1280, 1600, 1920].filter(
(w) => w <= width,
);
if (!responsiveWidths.includes(width)) {
responsiveWidths.push(width);
}
const srcset = builder
? responsiveWidths
.map((w) => {
const h = Math.round(w * aspect);
const u = builder.width(w).height(h).quality(quality).url();
return `${u} ${w}w`;
})
.join(", ")
: undefined;
// stegaClean: alt lands in an attribute, where stega's zero-width characters
// would be read out verbatim by screen readers.
const rawAlt = stegaClean((image as { alt?: string } | null)?.alt);
const alt = rawAlt && rawAlt.trim().length > 0 ? rawAlt : fallbackAlt;
---
<div class="transition-shadow duration-200 shadow-md group-hover:shadow-lg sm:mx-0">
{
src ? (
<img
class={className}
src={src}
srcset={srcset}
width={width}
height={height}
alt={alt}
loading={priority ? "eager" : "lazy"}
fetchpriority={priority ? "high" : "auto"}
decoding={priority ? "sync" : "async"}
sizes={sizes}
/>
) : (
<div class="bg-muted rounded-md" style="padding-top: 50%" />
)
}
</div>