Skip to content

Commit ea11fb9

Browse files
committed
Expose width based loaders
1 parent f00ff35 commit ea11fb9

File tree

2 files changed

+56
-13
lines changed

2 files changed

+56
-13
lines changed

packages/contentful/src/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import ContentfulVisual from './ContentfulVisual'
1+
import ContentfulVisual from "./ContentfulVisual";
22

3-
export default ContentfulVisual
3+
export default ContentfulVisual;
44
export type {
55
ContentfulVisualProps,
66
ContentfulImageAsset,
77
ContentfulAsset,
88
ContentfulVisualEntry,
9-
} from './types/contentfulVisualTypes'
9+
} from "./types/contentfulVisualTypes";
10+
export {
11+
orientationBasedImageLoader,
12+
orientationBasedVideoLoader,
13+
widthBasedImageLoader,
14+
widthBasedVideoLoader,
15+
} from "./lib/urlBuilding";

packages/contentful/src/lib/urlBuilding.ts

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { ImageLoader, VideoLoader } from "@react-visual/react";
44
export const contentfulModernFormats = ["image/avif", "image/webp"];
55

66
// Produce Contentful image URls based on screen orientation
7-
export const defaultImageLoader: ImageLoader = ({
7+
export const orientationBasedImageLoader: ImageLoader = ({
88
src,
99
width,
1010
type,
@@ -19,21 +19,58 @@ export const defaultImageLoader: ImageLoader = ({
1919
// If no URL found, return nothing
2020
if (!url) return "";
2121

22-
// Make Contentful resizing instructions
23-
const query = new URLSearchParams({ w: String(width) });
24-
25-
// Optionally set the format
26-
if (type?.includes("avif")) query.set("fm", "avif");
27-
else if (type?.includes("webp")) query.set("fm", "webp");
28-
2922
// Make the query with formatting instructions
30-
return `${url}?${query}`;
23+
return `${url}?${makeImageQueryParams({ width, type })}`;
3124
};
3225

3326
// Use portrait video from `src` prop or fallback to url based on screen
3427
// orientation
35-
export const defaultVideoLoader: VideoLoader = ({ src, media }) => {
28+
export const orientationBasedVideoLoader: VideoLoader = ({ src, media }) => {
3629
return media?.includes("portrait") && src.portraitVideo
3730
? src.portraitVideo.url
3831
: src.video?.url || src.url;
3932
};
33+
34+
// Produce Contentful image URls based on viewport width
35+
export const widthBasedImageLoader: ImageLoader = ({
36+
src,
37+
width,
38+
type,
39+
media,
40+
}) => {
41+
// Use portrait image if it exists, otherwise fallback to landscape
42+
const url =
43+
media?.includes("max-width") && src.portraitImage
44+
? src.portraitImage.url
45+
: src.image?.url || src.url;
46+
47+
// If no URL found, return nothing
48+
if (!url) return "";
49+
50+
// Make the query with formatting instructions
51+
return `${url}?${makeImageQueryParams({ width, type })}`;
52+
};
53+
54+
// Use portrait video from `src` prop or fallback to url based on viewport width
55+
export const widthBasedVideoLoader: VideoLoader = ({ src, media }) => {
56+
return media?.includes("max-width") && src.portraitVideo
57+
? src.portraitVideo.url
58+
: src.video?.url || src.url;
59+
};
60+
61+
// Helper to make the Contentful query params
62+
export function makeImageQueryParams({
63+
width,
64+
type,
65+
}: Pick<Parameters<ImageLoader>[0], "type" | "width">) {
66+
const query = new URLSearchParams({ w: String(width) });
67+
if (type?.includes("avif")) query.set("fm", "avif");
68+
else if (type?.includes("webp")) query.set("fm", "webp");
69+
return query;
70+
}
71+
72+
// Backwards compatibility exports
73+
export {
74+
orientationBasedImageLoader as defaultImageLoader,
75+
orientationBasedVideoLoader as defaultVideoLoader,
76+
};

0 commit comments

Comments
 (0)