From d41cdb12d89b35d2677d653bd70d691ce1e85bdc Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Tue, 15 Dec 2020 12:02:45 +0000 Subject: [PATCH] fix(gatsby-plugin-image): Better propType handling for StaticImage (#28606) * fix(gatsby-plugin-image): Better propType handling for StaticImage * Normalise props * Handle tracedSVG not being camel case (cherry picked from commit 52027db80559a728d4a85c729d282ec3abccf5b2) --- .../gatsby-static-image/src/pages/fluid.js | 1 + packages/gatsby-plugin-image/package.json | 1 + .../src/__tests__/babel-utils.ts | 42 +++++++++++++++++++ .../gatsby-plugin-image/src/babel-helpers.ts | 28 ++++++++++++- .../src/components/static-image.server.tsx | 14 +++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 packages/gatsby-plugin-image/src/__tests__/babel-utils.ts diff --git a/e2e-tests/gatsby-static-image/src/pages/fluid.js b/e2e-tests/gatsby-static-image/src/pages/fluid.js index c662b406ad30a..4aa8111020a95 100644 --- a/e2e-tests/gatsby-static-image/src/pages/fluid.js +++ b/e2e-tests/gatsby-static-image/src/pages/fluid.js @@ -9,6 +9,7 @@ const FluidPage = () => ( diff --git a/packages/gatsby-plugin-image/package.json b/packages/gatsby-plugin-image/package.json index fc5216b66ff75..dd324e19eb185 100644 --- a/packages/gatsby-plugin-image/package.json +++ b/packages/gatsby-plugin-image/package.json @@ -84,6 +84,7 @@ "@babel/traverse": "^7.12.5", "babel-jsx-utils": "^1.0.1", "babel-plugin-remove-graphql-queries": "^2.13.0-next.0", + "camelcase": "^5.3.1", "chokidar": "^3.4.3", "fs-extra": "^8.1.0", "gatsby-core-utils": "^1.7.0-next.0", diff --git a/packages/gatsby-plugin-image/src/__tests__/babel-utils.ts b/packages/gatsby-plugin-image/src/__tests__/babel-utils.ts new file mode 100644 index 0000000000000..7bb27bb762c1b --- /dev/null +++ b/packages/gatsby-plugin-image/src/__tests__/babel-utils.ts @@ -0,0 +1,42 @@ +import { normalizeProps } from "../babel-helpers" + +describe(`static-image babel parser`, () => { + it(`normalises props`, () => { + const input = { + formats: [`webP`, `JPG`, `png`], + placeholder: `DOMINANT_COLOR`, + layout: `FLUID`, + } + expect(normalizeProps(input)).toEqual({ + formats: [`webp`, `jpg`, `png`], + layout: `fluid`, + placeholder: `dominantColor`, + }) + }) + + it(`handles tracedSvg`, () => { + expect( + normalizeProps({ + placeholder: `TRACED_SVG`, + }) + ).toEqual({ + placeholder: `tracedSVG`, + }) + + expect( + normalizeProps({ + placeholder: `tracedSVG`, + }) + ).toEqual({ + placeholder: `tracedSVG`, + }) + + expect( + normalizeProps({ + placeholder: `tracedSvg`, + }) + ).toEqual({ + placeholder: `tracedSVG`, + }) + }) +}) diff --git a/packages/gatsby-plugin-image/src/babel-helpers.ts b/packages/gatsby-plugin-image/src/babel-helpers.ts index fbbc8101cab26..1bdbdcb19085d 100644 --- a/packages/gatsby-plugin-image/src/babel-helpers.ts +++ b/packages/gatsby-plugin-image/src/babel-helpers.ts @@ -2,6 +2,7 @@ import { murmurhash } from "babel-plugin-remove-graphql-queries/murmur" import { JSXOpeningElement } from "@babel/types" import { NodePath } from "@babel/core" import { getAttributeValues } from "babel-jsx-utils" +import camelCase from "camelcase" export const SHARP_ATTRIBUTES = new Set([ `src`, @@ -22,12 +23,37 @@ export const SHARP_ATTRIBUTES = new Set([ `background`, ]) +export function normalizeProps( + props: Record +): Record { + const out = { + ...props, + } + + if (out.layout) { + out.layout = camelCase(out.layout as string) + } + + if (out.placeholder) { + out.placeholder = camelCase(out.placeholder as string) + if (out.placeholder === `tracedSvg`) { + out.placeholder = `tracedSVG` + } + } + + if (Array.isArray(out.formats)) { + out.formats = out.formats.map((format: string) => format.toLowerCase()) + } + + return out +} + export function evaluateImageAttributes( nodePath: NodePath, onError?: (prop: string) => void ): Record { // Only get attributes that we need for generating the images - return getAttributeValues(nodePath, onError, SHARP_ATTRIBUTES) + return normalizeProps(getAttributeValues(nodePath, onError, SHARP_ATTRIBUTES)) } export function hashOptions(options: unknown): string { diff --git a/packages/gatsby-plugin-image/src/components/static-image.server.tsx b/packages/gatsby-plugin-image/src/components/static-image.server.tsx index d01678784ff63..e97a65a827f1f 100644 --- a/packages/gatsby-plugin-image/src/components/static-image.server.tsx +++ b/packages/gatsby-plugin-image/src/components/static-image.server.tsx @@ -111,6 +111,8 @@ const checkDimensionProps: PropTypes.Validator = ( return PropTypes.number(props, propName, ...rest) } +const validLayouts = new Set([`fixed`, `fluid`, `constrained`]) + export const propTypes = { src: PropTypes.string.isRequired, alt: PropTypes.string.isRequired, @@ -119,6 +121,18 @@ export const propTypes = { maxHeight: checkDimensionProps, maxWidth: checkDimensionProps, sizes: PropTypes.string, + layout: (props: IStaticImageProps & IPrivateProps): Error | undefined => { + if (props.layout === undefined) { + return undefined + } + if (validLayouts.has(props.layout.toLowerCase())) { + return undefined + } + + return new Error( + `Invalid value ${props.layout}" provided for prop "layout". Defaulting to "fixed". Valid values are "fixed", "fluid" or "constrained"` + ) + }, } StaticImage.displayName = `StaticImage`