Skip to content

Commit

Permalink
fix(PrismicImage): allow removing Imgix params in React Server Compon…
Browse files Browse the repository at this point in the history
…ents using `null` (#188)
  • Loading branch information
angeloashmore authored Jun 16, 2023
1 parent 323d6fc commit 2b17327
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 15 deletions.
32 changes: 19 additions & 13 deletions src/PrismicImage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from "react";
import * as prismic from "@prismicio/client";
import { ImgixURLParams } from "imgix-url-builder";

import { devMsg } from "./lib/devMsg";

Expand All @@ -23,7 +24,7 @@ export type PrismicImageProps = Omit<
*
* See: https://docs.imgix.com/apis/rendering
*/
imgixParams?: Parameters<typeof prismic.asImageSrc>[1];
imgixParams?: { [P in keyof ImgixURLParams]: ImgixURLParams[P] | null };

/**
* Declare an image as decorative by providing `alt=""`.
Expand Down Expand Up @@ -103,24 +104,22 @@ export type PrismicImageProps = Omit<
* @returns A responsive image component for the given Image field.
*/
export const PrismicImage = React.forwardRef(function PrismicImage(
props: PrismicImageProps,
ref: React.ForwardedRef<HTMLImageElement>,
): JSX.Element | null {
const {
{
field,
alt,
fallbackAlt,
imgixParams,
imgixParams = {},
widths,
pixelDensities,
...restProps
} = props;

}: PrismicImageProps,
ref: React.ForwardedRef<HTMLImageElement>,
): JSX.Element | null {
if (
typeof process !== "undefined" &&
process.env.NODE_ENV === "development"
) {
if (typeof alt === "string" && props.alt !== "") {
if (typeof alt === "string" && alt !== "") {
console.warn(
`[PrismicImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg(
"alt-must-be-an-empty-string",
Expand All @@ -144,23 +143,30 @@ export const PrismicImage = React.forwardRef(function PrismicImage(
}

if (prismic.isFilled.imageThumbnail(field)) {
const resolvedImgixParams = imgixParams;
for (const x in imgixParams) {
if (resolvedImgixParams[x as keyof typeof resolvedImgixParams] === null) {
resolvedImgixParams[x as keyof typeof resolvedImgixParams] = undefined;
}
}

let src: string | undefined;
let srcSet: string | undefined;

if (widths || !pixelDensities) {
const res = prismic.asImageWidthSrcSet(field, {
...imgixParams,
...resolvedImgixParams,
widths: widths === "defaults" ? undefined : widths,
});
} as ImgixURLParams);

src = res.src;
srcSet = res.srcset;
} else if (pixelDensities) {
const res = prismic.asImagePixelDensitySrcSet(field, {
...imgixParams,
...resolvedImgixParams,
pixelDensities:
pixelDensities === "defaults" ? undefined : pixelDensities,
});
} as ImgixURLParams);

src = res.src;
srcSet = res.srcset;
Expand Down
30 changes: 30 additions & 0 deletions test/PrismicImage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,33 @@ it("supports imgix parameters", async (ctx) => {

expect(actual).toStrictEqual(expected);
});

it("allows removing existing Imgix params via the imgixParams prop", async (ctx) => {
const field = ctx.mock.value.image({
model: ctx.mock.model.image(),
});
const fieldURL = new URL(field.url);
fieldURL.searchParams.set("auto", "compress,format");
fieldURL.searchParams.set("sat", "-100");
fieldURL.searchParams.set("ar", "1:2");
field.url = fieldURL.toString();

const img = renderJSON(
<PrismicImage
field={field}
imgixParams={{
auto: undefined,
// React Server Components removes `undefined`
// from objects, so we also support `null` as an
// explicit value to remove a param.
sat: null,
}}
/>,
);

const src = new URL(img?.props.src);

expect(src.searchParams.get("auto")).toBe(null);
expect(src.searchParams.get("sat")).toBe(null);
expect(src.searchParams.get("ar")).toBe("1:2");
});
4 changes: 2 additions & 2 deletions test/__testutils__/renderJSON.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import * as renderer from "react-test-renderer";
export const renderJSON = (
element: React.ReactElement,
options?: renderer.TestRendererOptions,
): renderer.ReactTestRendererJSON | renderer.ReactTestRendererJSON[] | null => {
): renderer.ReactTestRendererJSON | null => {
let root: renderer.ReactTestRenderer;

renderer.act(() => {
root = renderer.create(element, options);
});

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return root!.toJSON();
return root!.toJSON() as renderer.ReactTestRendererJSON;
};

0 comments on commit 2b17327

Please sign in to comment.