Skip to content

Commit

Permalink
feat(gatsby-plugin-image): Allow image helpers to take other node typ…
Browse files Browse the repository at this point in the history
…es (#29625)

* feat(gatsby-plugin-image): Allow image helpers to take other node types

* Allow passing data to the helpers

* Address comments from review
  • Loading branch information
ascorbic committed Feb 22, 2021
1 parent 7a8c0ac commit eaab2df
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 7 deletions.
113 changes: 113 additions & 0 deletions packages/gatsby-plugin-image/src/components/__tests__/hooks.ts
@@ -0,0 +1,113 @@
import { Node } from "gatsby"
import { getSrc, getSrcSet, getImage, IGatsbyImageData } from "../../"

const imageData: IGatsbyImageData = {
images: {
fallback: {
src: `imagesrc.jpg`,
srcSet: `imagesrcset.jpg 1x`,
},
},
layout: `constrained`,
width: 1,
height: 2,
}

const node: Node = {
id: ``,
parent: ``,
children: [],
internal: {
type: ``,
contentDigest: ``,
owner: ``,
},
}

const dataParent = {
...node,
gatsbyImageData: imageData,
}

const fileNode = {
...node,
childImageSharp: dataParent,
}

describe(`The image helper functions`, () => {
describe(`getImage`, () => {
it(`returns the same data if passed gatsbyImageData`, () => {
expect(getImage(imageData)).toEqual(imageData)
})

it(`gets an image from a FileNode`, () => {
expect(getImage(fileNode)?.images.fallback?.src).toEqual(`imagesrc.jpg`)
})

it(`gets an image from an IGatsbyImageDataParent`, () => {
expect(getImage(dataParent)?.images.fallback?.src).toEqual(`imagesrc.jpg`)
})
it(`returns undefined from an invalid object`, () => {
expect(getImage(node)).toBeUndefined()
})

it(`returns undefined when passed a number`, () => {
expect(getImage((1 as any) as Node)).toBeUndefined()
})

it(`returns undefined when passed undefined`, () => {
expect(getImage((undefined as any) as Node)).toBeUndefined()
})
})

describe(`getSrc`, () => {
it(`gets src from an image data object`, () => {
expect(getSrc(imageData)).toEqual(`imagesrc.jpg`)
})

it(`gets src from a FileNode`, () => {
expect(getSrc(fileNode)).toEqual(`imagesrc.jpg`)
})

it(`gets src from an IGatsbyImageDataParent`, () => {
expect(getSrc(dataParent)).toEqual(`imagesrc.jpg`)
})

it(`returns undefined from an invalid object`, () => {
expect(getSrc(node)).toBeUndefined()
})
it(`returns undefined when passed undefined`, () => {
expect(getSrc((undefined as any) as Node)).toBeUndefined()
})

it(`returns undefined when passed a number`, () => {
expect(getSrc((1 as any) as Node)).toBeUndefined()
})
})

describe(`getSrcSet`, () => {
it(`gets srcSet from am image data object`, () => {
expect(getSrcSet(imageData)).toEqual(`imagesrcset.jpg 1x`)
})

it(`gets srcSet from a FileNode`, () => {
expect(getSrcSet(fileNode)).toEqual(`imagesrcset.jpg 1x`)
})

it(`gets srcSet from an IGatsbyImageDataParent`, () => {
expect(getSrcSet(dataParent)).toEqual(`imagesrcset.jpg 1x`)
})

it(`returns undefined from an invalid object`, () => {
expect(getSrcSet(node)).toBeUndefined()
})

it(`returns undefined when passed undefined`, () => {
expect(getSrcSet((undefined as any) as Node)).toBeUndefined()
})

it(`returns undefined when passed a number`, () => {
expect(getSrcSet((1 as any) as Node)).toBeUndefined()
})
})
})
37 changes: 30 additions & 7 deletions packages/gatsby-plugin-image/src/components/hooks.ts
Expand Up @@ -38,18 +38,41 @@ export function storeImageloaded(cacheKey?: string): void {
export function hasImageLoaded(cacheKey: string): boolean {
return imageCache.has(cacheKey)
}

export type IGatsbyImageDataParent<T = never> = T & {
gatsbyImageData: IGatsbyImageData
}
export type FileNode = Node & {
childImageSharp?: Node & {
gatsbyImageData?: IGatsbyImageData
childImageSharp?: IGatsbyImageDataParent<Node>
}

const isGatsbyImageData = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
node: IGatsbyImageData | any
): node is IGatsbyImageData =>
// 🦆 check for a deep prop to be sure this is a valid gatsbyImageData object
Boolean(node?.images?.fallback?.src)

const isGatsbyImageDataParent = <T>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
node: IGatsbyImageDataParent<T> | any
): node is IGatsbyImageDataParent<T> => Boolean(node?.gatsbyImageData)

type ImageDataLike = FileNode | IGatsbyImageDataParent | IGatsbyImageData
export const getImage = (node: ImageDataLike): IGatsbyImageData | undefined => {
if (isGatsbyImageData(node)) {
return node
}
if (isGatsbyImageDataParent(node)) {
return node.gatsbyImageData
}
return node?.childImageSharp?.gatsbyImageData
}

export const getImage = (file: FileNode): IGatsbyImageData | undefined =>
file?.childImageSharp?.gatsbyImageData
export const getSrc = (node: ImageDataLike): string | undefined =>
getImage(node)?.images?.fallback?.src

export const getSrc = (file: FileNode): string | undefined =>
file?.childImageSharp?.gatsbyImageData?.images?.fallback?.src
export const getSrcSet = (node: ImageDataLike): string | undefined =>
getImage(node)?.images?.fallback?.srcSet

export function getWrapperProps(
width: number,
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby-plugin-image/src/index.browser.ts
Expand Up @@ -10,6 +10,7 @@ export { LaterHydrator } from "./components/later-hydrator"
export {
getImage,
getSrc,
getSrcSet,
getImageData,
withArtDirection,
IArtDirectedImage,
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby-plugin-image/src/index.ts
Expand Up @@ -9,6 +9,7 @@ export { StaticImage } from "./components/static-image.server"
export {
getImage,
getSrc,
getSrcSet,
getImageData,
withArtDirection,
IArtDirectedImage,
Expand Down

0 comments on commit eaab2df

Please sign in to comment.