Skip to content

Commit 5901a10

Browse files
LekoArtsascorbic
andauthored
fix(gatsby-plugin-image): Better propType handling for StaticImage (#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 <[email protected]>
1 parent 81175a5 commit 5901a10

File tree

5 files changed

+85
-1
lines changed

5 files changed

+85
-1
lines changed

e2e-tests/gatsby-static-image/src/pages/fluid.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const FluidPage = () => (
99
<StaticImage
1010
src="../images/citrus-fruits.jpg"
1111
layout="fluid"
12+
maxWidth={700}
1213
alt="Citrus fruits"
1314
/>
1415
</div>

packages/gatsby-plugin-image/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"@babel/traverse": "^7.12.5",
8585
"babel-jsx-utils": "^1.0.1",
8686
"babel-plugin-remove-graphql-queries": "^2.13.0-next.0",
87+
"camelcase": "^5.3.1",
8788
"chokidar": "^3.4.3",
8889
"fs-extra": "^8.1.0",
8990
"gatsby-core-utils": "^1.7.0-next.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { normalizeProps } from "../babel-helpers"
2+
3+
describe(`static-image babel parser`, () => {
4+
it(`normalises props`, () => {
5+
const input = {
6+
formats: [`webP`, `JPG`, `png`],
7+
placeholder: `DOMINANT_COLOR`,
8+
layout: `FLUID`,
9+
}
10+
expect(normalizeProps(input)).toEqual({
11+
formats: [`webp`, `jpg`, `png`],
12+
layout: `fluid`,
13+
placeholder: `dominantColor`,
14+
})
15+
})
16+
17+
it(`handles tracedSvg`, () => {
18+
expect(
19+
normalizeProps({
20+
placeholder: `TRACED_SVG`,
21+
})
22+
).toEqual({
23+
placeholder: `tracedSVG`,
24+
})
25+
26+
expect(
27+
normalizeProps({
28+
placeholder: `tracedSVG`,
29+
})
30+
).toEqual({
31+
placeholder: `tracedSVG`,
32+
})
33+
34+
expect(
35+
normalizeProps({
36+
placeholder: `tracedSvg`,
37+
})
38+
).toEqual({
39+
placeholder: `tracedSVG`,
40+
})
41+
})
42+
})

packages/gatsby-plugin-image/src/babel-helpers.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { murmurhash } from "babel-plugin-remove-graphql-queries/murmur"
22
import { JSXOpeningElement } from "@babel/types"
33
import { NodePath } from "@babel/core"
44
import { getAttributeValues } from "babel-jsx-utils"
5+
import camelCase from "camelcase"
56

67
export const SHARP_ATTRIBUTES = new Set([
78
`src`,
@@ -22,12 +23,37 @@ export const SHARP_ATTRIBUTES = new Set([
2223
`background`,
2324
])
2425

26+
export function normalizeProps(
27+
props: Record<string, unknown>
28+
): Record<string, unknown> {
29+
const out = {
30+
...props,
31+
}
32+
33+
if (out.layout) {
34+
out.layout = camelCase(out.layout as string)
35+
}
36+
37+
if (out.placeholder) {
38+
out.placeholder = camelCase(out.placeholder as string)
39+
if (out.placeholder === `tracedSvg`) {
40+
out.placeholder = `tracedSVG`
41+
}
42+
}
43+
44+
if (Array.isArray(out.formats)) {
45+
out.formats = out.formats.map((format: string) => format.toLowerCase())
46+
}
47+
48+
return out
49+
}
50+
2551
export function evaluateImageAttributes(
2652
nodePath: NodePath<JSXOpeningElement>,
2753
onError?: (prop: string) => void
2854
): Record<string, unknown> {
2955
// Only get attributes that we need for generating the images
30-
return getAttributeValues(nodePath, onError, SHARP_ATTRIBUTES)
56+
return normalizeProps(getAttributeValues(nodePath, onError, SHARP_ATTRIBUTES))
3157
}
3258

3359
export function hashOptions(options: unknown): string {

packages/gatsby-plugin-image/src/components/static-image.server.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ const checkDimensionProps: PropTypes.Validator<number> = (
111111
return PropTypes.number(props, propName, ...rest)
112112
}
113113

114+
const validLayouts = new Set([`fixed`, `fluid`, `constrained`])
115+
114116
export const propTypes = {
115117
src: PropTypes.string.isRequired,
116118
alt: PropTypes.string.isRequired,
@@ -119,6 +121,18 @@ export const propTypes = {
119121
maxHeight: checkDimensionProps,
120122
maxWidth: checkDimensionProps,
121123
sizes: PropTypes.string,
124+
layout: (props: IStaticImageProps & IPrivateProps): Error | undefined => {
125+
if (props.layout === undefined) {
126+
return undefined
127+
}
128+
if (validLayouts.has(props.layout.toLowerCase())) {
129+
return undefined
130+
}
131+
132+
return new Error(
133+
`Invalid value ${props.layout}" provided for prop "layout". Defaulting to "fixed". Valid values are "fixed", "fluid" or "constrained"`
134+
)
135+
},
122136
}
123137

124138
StaticImage.displayName = `StaticImage`

0 commit comments

Comments
 (0)