Skip to content

Commit eaab2df

Browse files
authored
feat(gatsby-plugin-image): Allow image helpers to take other node types (#29625)
* feat(gatsby-plugin-image): Allow image helpers to take other node types * Allow passing data to the helpers * Address comments from review
1 parent 7a8c0ac commit eaab2df

File tree

4 files changed

+145
-7
lines changed

4 files changed

+145
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { Node } from "gatsby"
2+
import { getSrc, getSrcSet, getImage, IGatsbyImageData } from "../../"
3+
4+
const imageData: IGatsbyImageData = {
5+
images: {
6+
fallback: {
7+
src: `imagesrc.jpg`,
8+
srcSet: `imagesrcset.jpg 1x`,
9+
},
10+
},
11+
layout: `constrained`,
12+
width: 1,
13+
height: 2,
14+
}
15+
16+
const node: Node = {
17+
id: ``,
18+
parent: ``,
19+
children: [],
20+
internal: {
21+
type: ``,
22+
contentDigest: ``,
23+
owner: ``,
24+
},
25+
}
26+
27+
const dataParent = {
28+
...node,
29+
gatsbyImageData: imageData,
30+
}
31+
32+
const fileNode = {
33+
...node,
34+
childImageSharp: dataParent,
35+
}
36+
37+
describe(`The image helper functions`, () => {
38+
describe(`getImage`, () => {
39+
it(`returns the same data if passed gatsbyImageData`, () => {
40+
expect(getImage(imageData)).toEqual(imageData)
41+
})
42+
43+
it(`gets an image from a FileNode`, () => {
44+
expect(getImage(fileNode)?.images.fallback?.src).toEqual(`imagesrc.jpg`)
45+
})
46+
47+
it(`gets an image from an IGatsbyImageDataParent`, () => {
48+
expect(getImage(dataParent)?.images.fallback?.src).toEqual(`imagesrc.jpg`)
49+
})
50+
it(`returns undefined from an invalid object`, () => {
51+
expect(getImage(node)).toBeUndefined()
52+
})
53+
54+
it(`returns undefined when passed a number`, () => {
55+
expect(getImage((1 as any) as Node)).toBeUndefined()
56+
})
57+
58+
it(`returns undefined when passed undefined`, () => {
59+
expect(getImage((undefined as any) as Node)).toBeUndefined()
60+
})
61+
})
62+
63+
describe(`getSrc`, () => {
64+
it(`gets src from an image data object`, () => {
65+
expect(getSrc(imageData)).toEqual(`imagesrc.jpg`)
66+
})
67+
68+
it(`gets src from a FileNode`, () => {
69+
expect(getSrc(fileNode)).toEqual(`imagesrc.jpg`)
70+
})
71+
72+
it(`gets src from an IGatsbyImageDataParent`, () => {
73+
expect(getSrc(dataParent)).toEqual(`imagesrc.jpg`)
74+
})
75+
76+
it(`returns undefined from an invalid object`, () => {
77+
expect(getSrc(node)).toBeUndefined()
78+
})
79+
it(`returns undefined when passed undefined`, () => {
80+
expect(getSrc((undefined as any) as Node)).toBeUndefined()
81+
})
82+
83+
it(`returns undefined when passed a number`, () => {
84+
expect(getSrc((1 as any) as Node)).toBeUndefined()
85+
})
86+
})
87+
88+
describe(`getSrcSet`, () => {
89+
it(`gets srcSet from am image data object`, () => {
90+
expect(getSrcSet(imageData)).toEqual(`imagesrcset.jpg 1x`)
91+
})
92+
93+
it(`gets srcSet from a FileNode`, () => {
94+
expect(getSrcSet(fileNode)).toEqual(`imagesrcset.jpg 1x`)
95+
})
96+
97+
it(`gets srcSet from an IGatsbyImageDataParent`, () => {
98+
expect(getSrcSet(dataParent)).toEqual(`imagesrcset.jpg 1x`)
99+
})
100+
101+
it(`returns undefined from an invalid object`, () => {
102+
expect(getSrcSet(node)).toBeUndefined()
103+
})
104+
105+
it(`returns undefined when passed undefined`, () => {
106+
expect(getSrcSet((undefined as any) as Node)).toBeUndefined()
107+
})
108+
109+
it(`returns undefined when passed a number`, () => {
110+
expect(getSrcSet((1 as any) as Node)).toBeUndefined()
111+
})
112+
})
113+
})

packages/gatsby-plugin-image/src/components/hooks.ts

+30-7
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,41 @@ export function storeImageloaded(cacheKey?: string): void {
3838
export function hasImageLoaded(cacheKey: string): boolean {
3939
return imageCache.has(cacheKey)
4040
}
41-
41+
export type IGatsbyImageDataParent<T = never> = T & {
42+
gatsbyImageData: IGatsbyImageData
43+
}
4244
export type FileNode = Node & {
43-
childImageSharp?: Node & {
44-
gatsbyImageData?: IGatsbyImageData
45+
childImageSharp?: IGatsbyImageDataParent<Node>
46+
}
47+
48+
const isGatsbyImageData = (
49+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
50+
node: IGatsbyImageData | any
51+
): node is IGatsbyImageData =>
52+
// 🦆 check for a deep prop to be sure this is a valid gatsbyImageData object
53+
Boolean(node?.images?.fallback?.src)
54+
55+
const isGatsbyImageDataParent = <T>(
56+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
57+
node: IGatsbyImageDataParent<T> | any
58+
): node is IGatsbyImageDataParent<T> => Boolean(node?.gatsbyImageData)
59+
60+
type ImageDataLike = FileNode | IGatsbyImageDataParent | IGatsbyImageData
61+
export const getImage = (node: ImageDataLike): IGatsbyImageData | undefined => {
62+
if (isGatsbyImageData(node)) {
63+
return node
64+
}
65+
if (isGatsbyImageDataParent(node)) {
66+
return node.gatsbyImageData
4567
}
68+
return node?.childImageSharp?.gatsbyImageData
4669
}
4770

48-
export const getImage = (file: FileNode): IGatsbyImageData | undefined =>
49-
file?.childImageSharp?.gatsbyImageData
71+
export const getSrc = (node: ImageDataLike): string | undefined =>
72+
getImage(node)?.images?.fallback?.src
5073

51-
export const getSrc = (file: FileNode): string | undefined =>
52-
file?.childImageSharp?.gatsbyImageData?.images?.fallback?.src
74+
export const getSrcSet = (node: ImageDataLike): string | undefined =>
75+
getImage(node)?.images?.fallback?.srcSet
5376

5477
export function getWrapperProps(
5578
width: number,

packages/gatsby-plugin-image/src/index.browser.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export { LaterHydrator } from "./components/later-hydrator"
1010
export {
1111
getImage,
1212
getSrc,
13+
getSrcSet,
1314
getImageData,
1415
withArtDirection,
1516
IArtDirectedImage,

packages/gatsby-plugin-image/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export { StaticImage } from "./components/static-image.server"
99
export {
1010
getImage,
1111
getSrc,
12+
getSrcSet,
1213
getImageData,
1314
withArtDirection,
1415
IArtDirectedImage,

0 commit comments

Comments
 (0)