Skip to content

Commit

Permalink
fix(gatsby-plugin-image): Better propType handling for StaticImage (#…
Browse files Browse the repository at this point in the history
…28606) (#28628)

* fix(gatsby-plugin-image): Better propType handling for StaticImage

* Normalise props

* Handle tracedSVG not being camel case

(cherry picked from commit 52027db)

Co-authored-by: Matt Kane <matt@gatsbyjs.com>
  • Loading branch information
LekoArts and ascorbic committed Dec 15, 2020
1 parent 81175a5 commit 5901a10
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
1 change: 1 addition & 0 deletions e2e-tests/gatsby-static-image/src/pages/fluid.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const FluidPage = () => (
<StaticImage
src="../images/citrus-fruits.jpg"
layout="fluid"
maxWidth={700}
alt="Citrus fruits"
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby-plugin-image/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
42 changes: 42 additions & 0 deletions packages/gatsby-plugin-image/src/__tests__/babel-utils.ts
Original file line number Diff line number Diff line change
@@ -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`,
})
})
})
28 changes: 27 additions & 1 deletion packages/gatsby-plugin-image/src/babel-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
Expand All @@ -22,12 +23,37 @@ export const SHARP_ATTRIBUTES = new Set([
`background`,
])

export function normalizeProps(
props: Record<string, unknown>
): Record<string, unknown> {
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<JSXOpeningElement>,
onError?: (prop: string) => void
): Record<string, unknown> {
// 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ const checkDimensionProps: PropTypes.Validator<number> = (
return PropTypes.number(props, propName, ...rest)
}

const validLayouts = new Set([`fixed`, `fluid`, `constrained`])

export const propTypes = {
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
Expand All @@ -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`
Expand Down

0 comments on commit 5901a10

Please sign in to comment.