Skip to content

feat(gatsby-image): Add art direction #13395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Jun 21, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2d269f3
Add optional media key to PropTypes and Typescript declarations
brimtown Apr 8, 2019
2ce14e0
Add optional fluidImages and fixedImages props
brimtown Apr 10, 2019
c9f2f36
Add art direction to fixed and fluid images
brimtown Apr 10, 2019
5d3ecb1
Add art direction to base64 and tracedSVG
brimtown Apr 10, 2019
79d557c
Add art direction to noscript image
brimtown Apr 16, 2019
cf3c58c
Add tests for fixedImages and fluidImages
brimtown Apr 16, 2019
46dc731
Merge remote-tracking branch 'upstream/master' into feat/add-image-ar…
pieh Apr 16, 2019
6282c75
Respond to code review
brimtown Apr 30, 2019
da6b873
Merge remote-tracking branch 'upstream/master' into feat/add-image-ar…
brimtown Apr 30, 2019
fc12f62
Use const in tests
brimtown Apr 30, 2019
03226cb
Merge remote-tracking branch 'upstream/master' into feat/add-image-ar…
brimtown May 16, 2019
5317331
Merge branch 'feat/add-image-art-direction' of github.com:brimtown/ga…
brimtown May 16, 2019
f283cad
Merge remote-tracking branch 'upstream/master' into feat/add-image-ar…
brimtown May 16, 2019
e81b2b7
Additinal code review refactor
brimtown May 23, 2019
57363a5
Merge remote-tracking branch 'upstream/master' into feat/add-image-ar…
brimtown May 23, 2019
a58da9b
Fix e2e tests
brimtown May 27, 2019
a6d966d
Merge remote-tracking branch 'upstream/master' into feat/add-image-ar…
brimtown May 27, 2019
6f5bb09
Add README docs
brimtown May 28, 2019
b685421
Fix typo and update wording in README
brimtown May 28, 2019
4ba3b86
Name selectors in e2e test
brimtown May 30, 2019
c98c23d
Work around SVG bug by encoding spaces
brimtown Jun 11, 2019
5ceebb9
Fix breaking Placeholder change, respond to code review, and update s…
brimtown Jun 11, 2019
85c844a
Use @polarthene's Pastebin
brimtown Jun 11, 2019
d7b102a
Update sharp snapshot test
brimtown Jun 11, 2019
55063e3
Reset integration tests
brimtown Jun 11, 2019
91478a2
Merge branch 'master' into pr/13395
wardpeet Jun 17, 2019
9aa56b1
Move fluidImages & fixedImages into fluid & fixed
wardpeet Jun 17, 2019
a0d0c78
update tests with no media
wardpeet Jun 17, 2019
c298cc6
cleanup spreadprops
wardpeet Jun 17, 2019
9895126
Add warning if multiple sources with no media were used
wardpeet Jun 17, 2019
6257cdf
review changes
wardpeet Jun 18, 2019
836ce77
fix tests
wardpeet Jun 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/gatsby-image/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface FixedObject {
tracedSVG?: string
srcWebp?: string
srcSetWebp?: string
media?: string
}

interface FluidObject {
Expand All @@ -20,13 +21,16 @@ interface FluidObject {
tracedSVG?: string
srcWebp?: string
srcSetWebp?: string
media?: string
}

interface GatsbyImageProps {
resolutions?: FixedObject
sizes?: FluidObject
fixed?: FixedObject
fluid?: FluidObject
fixedImages?: FixedObject[]
fluidImages?: FluidObject[]
fadeIn?: boolean
title?: string
alt?: string
Expand Down
166 changes: 153 additions & 13 deletions packages/gatsby-image/src/__tests__/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ exports[`<Image /> should render fixed size images 1`] = `
style="background-color: lightgray; width: 100px; opacity: 1; height: 100px; transition-delay: 0.5s;"
title="Title for the image"
/>
<img
alt=""
class="placeholder"
src="string_of_base64"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 1; transition-delay: 0.5s; color: red;"
title="Title for the image"
/>
<picture>
<img
alt=""
class="placeholder"
src="string_of_base64"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 1; transition-delay: 0.5s; color: red;"
title="Title for the image"
/>
</picture>
<picture>
<source
srcset="some srcSetWebp"
Expand Down Expand Up @@ -54,19 +56,157 @@ exports[`<Image /> should render fluid images 1`] = `
style="background-color: lightgray; position: absolute; top: 0px; bottom: 0px; opacity: 1; right: 0px; left: 0px; transition-delay: 0.5s;"
title="Title for the image"
/>
<img
alt=""
class="placeholder"
src="string_of_base64"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 1; transition-delay: 0.5s; color: red;"
<picture>
<img
alt=""
class="placeholder"
src="string_of_base64"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 1; transition-delay: 0.5s; color: red;"
title="Title for the image"
/>
</picture>
<picture>
<source
sizes="(max-width: 600px) 100vw, 600px"
srcset="some srcSetWebp"
type="image/webp"
/>
<img
alt="Alt text for the image"
crossorigin="anonymous"
itemprop="item-prop-for-the-image"
sizes="(max-width: 600px) 100vw, 600px"
src="test_image.jpg"
srcset="some srcSet"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 0; transition: opacity 0.5s;"
title="Title for the image"
/>
</picture>
<noscript>
&lt;picture&gt;&lt;source type='image/webp' srcset="some srcSetWebp" sizes="(max-width: 600px) 100vw, 600px" /&gt;&lt;img sizes="(max-width: 600px) 100vw, 600px" srcset="some srcSet" src="test_image.jpg" alt="Alt text for the image" title="Title for the image" style="position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center"/&gt;&lt;/picture&gt;
</noscript>
</div>
</div>
`;

exports[`<Image /> should render multiple fixed image variants 1`] = `
<div>
<div
class="fixedImage gatsby-image-wrapper"
style="position: relative; overflow: hidden; display: inline; width: 100px; height: 100px;"
>
<div
style="background-color: lightgray; width: 100px; opacity: 1; height: 100px; transition-delay: 0.5s;"
title="Title for the image"
/>
<picture>
<source
media="only screen and (max-width: 767px)"
srcset="string_of_base64"
/>
<source
media="only screen and (min-width: 768px)"
srcset="other_string_of_base64"
/>
<img
alt=""
class="placeholder"
src="string_of_base64"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 1; transition-delay: 0.5s; color: red;"
title="Title for the image"
/>
</picture>
<picture>
<source
media="only screen and (max-width: 767px)"
srcset="some srcSetWebp"
type="image/webp"
/>
<source
media="only screen and (max-width: 767px)"
srcset="some srcSet"
/>
<source
media="only screen and (min-width: 768px)"
srcset="some other srcSetWebp"
type="image/webp"
/>
<source
media="only screen and (min-width: 768px)"
srcset="some other srcSet"
/>
<img
alt="Alt text for the image"
crossorigin="anonymous"
height="100"
itemprop="item-prop-for-the-image"
src="test_image.jpg"
srcset="some srcSet"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 0; transition: opacity 0.5s;"
title="Title for the image"
width="100"
/>
</picture>
<noscript>
&lt;picture&gt;&lt;source type='image/webp' srcSet="some srcSetWebp" media="only screen and (max-width: 767px)" /&gt;&lt;source srcSet="some srcSet" media="only screen and (max-width: 767px)" /&gt;,&lt;source type='image/webp' srcSet="some other srcSetWebp" media="only screen and (min-width: 768px)" /&gt;&lt;source srcSet="some other srcSet" media="only screen and (min-width: 768px)" /&gt;&lt;img width="100" height="100" srcset="some srcSet" src="test_image.jpg" alt="Alt text for the image" title="Title for the image" style="position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center"/&gt;&lt;/picture&gt;
</noscript>
</div>
</div>
`;

exports[`<Image /> should render multiple fluid image variants 1`] = `
<div>
<div
class="fixedImage gatsby-image-wrapper"
style="position: relative; overflow: hidden; display: inline;"
>
<div
style="width: 100%; padding-bottom: 66.66666666666667%;"
/>
<div
style="background-color: lightgray; position: absolute; top: 0px; bottom: 0px; opacity: 1; right: 0px; left: 0px; transition-delay: 0.5s;"
title="Title for the image"
/>
<picture>
<source
media="only screen and (max-width: 767px)"
srcset="string_of_base64"
/>
<source
media="only screen and (min-width: 768px)"
srcset="string_of_base64"
/>
<img
alt=""
class="placeholder"
src="string_of_base64"
style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center; opacity: 1; transition-delay: 0.5s; color: red;"
title="Title for the image"
/>
</picture>
<picture>
<source
media="only screen and (max-width: 767px)"
sizes="(max-width: 600px) 100vw, 600px"
srcset="some srcSetWebp"
type="image/webp"
/>
<source
media="only screen and (max-width: 767px)"
sizes="(max-width: 600px) 100vw, 600px"
srcset="some srcSet"
/>
<source
media="only screen and (min-width: 768px)"
sizes="(max-width: 600px) 100vw, 600px"
srcset="some other srcSetWebp"
type="image/webp"
/>
<source
media="only screen and (min-width: 768px)"
sizes="(max-width: 600px) 100vw, 600px"
srcset="some other srcSet"
/>
<img
alt="Alt text for the image"
crossorigin="anonymous"
Expand All @@ -79,7 +219,7 @@ exports[`<Image /> should render fluid images 1`] = `
/>
</picture>
<noscript>
&lt;picture&gt;&lt;source type='image/webp' srcset="some srcSetWebp" sizes="(max-width: 600px) 100vw, 600px" /&gt;&lt;img sizes="(max-width: 600px) 100vw, 600px" srcset="some srcSet" src="test_image.jpg" alt="Alt text for the image" title="Title for the image" style="position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center"/&gt;&lt;/picture&gt;
&lt;picture&gt;&lt;source type='image/webp' srcSet="some srcSetWebp" media="only screen and (max-width: 767px)" sizes="(max-width: 600px) 100vw, 600px" /&gt;&lt;source srcSet="some srcSet" media="only screen and (max-width: 767px)" sizes="(max-width: 600px) 100vw, 600px" /&gt;,&lt;source type='image/webp' srcSet="some other srcSetWebp" media="only screen and (min-width: 768px)" sizes="(max-width: 600px) 100vw, 600px" /&gt;&lt;source srcSet="some other srcSet" media="only screen and (min-width: 768px)" sizes="(max-width: 600px) 100vw, 600px" /&gt;&lt;img sizes="(max-width: 600px) 100vw, 600px" srcset="some srcSet" src="test_image.jpg" alt="Alt text for the image" title="Title for the image" style="position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center"/&gt;&lt;/picture&gt;
</noscript>
</div>
</div>
Expand Down
84 changes: 81 additions & 3 deletions packages/gatsby-image/src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,48 @@ const fluidShapeMock = {
base64: `string_of_base64`,
}

const fixedImagesShapeMock = [
{
width: 100,
height: 100,
src: `test_image.jpg`,
srcSet: `some srcSet`,
srcSetWebp: `some srcSetWebp`,
base64: `string_of_base64`,
media: `only screen and (max-width: 767px)`,
},
{
width: 100,
height: 100,
src: `test_image_2.jpg`,
srcSet: `some other srcSet`,
srcSetWebp: `some other srcSetWebp`,
base64: `other_string_of_base64`,
media: `only screen and (min-width: 768px)`,
},
]

const fluidImagesShapeMock = [
{
aspectRatio: 1.5,
src: `test_image.jpg`,
srcSet: `some srcSet`,
srcSetWebp: `some srcSetWebp`,
sizes: `(max-width: 600px) 100vw, 600px`,
base64: `string_of_base64`,
media: `only screen and (max-width: 767px)`,
},
{
aspectRatio: 2,
src: `test_image_2.jpg`,
srcSet: `some other srcSet`,
srcSetWebp: `some other srcSetWebp`,
sizes: `(max-width: 600px) 100vw, 600px`,
base64: `string_of_base64`,
media: `only screen and (min-width: 768px)`,
},
]

const setup = (fluid = false, onLoad = () => {}, onError = () => {}) => {
const { container } = render(
<Image
Expand All @@ -45,6 +87,32 @@ const setup = (fluid = false, onLoad = () => {}, onError = () => {}) => {
return container
}

const setupImages = (
fluidImages = false,
onLoad = () => {},
onError = () => {}
) => {
const { container } = render(
<Image
backgroundColor
className={`fixedImage`}
style={{ display: `inline` }}
title={`Title for the image`}
alt={`Alt text for the image`}
crossOrigin={`anonymous`}
{...fluidImages && { fluidImages: fluidImagesShapeMock }}
{...!fluidImages && { fixedImages: fixedImagesShapeMock }}
onLoad={onLoad}
onError={onError}
itemProp={`item-prop-for-the-image`}
placeholderStyle={{ color: `red` }}
placeholderClassName={`placeholder`}
/>
)

return container
}

describe(`<Image />`, () => {
it(`should render fixed size images`, () => {
const component = setup()
Expand All @@ -56,8 +124,18 @@ describe(`<Image />`, () => {
expect(component).toMatchSnapshot()
})

it(`should render multiple fixed image variants`, () => {
const component = setupImages()
expect(component).toMatchSnapshot()
})

it(`should render multiple fluid image variants`, () => {
const component = setupImages(true)
expect(component).toMatchSnapshot()
})

it(`should have correct src, title, alt, and crossOrigin attributes`, () => {
const imageTag = setup().querySelector(`picture img`)
const imageTag = setup().querySelectorAll(`picture img`)[1]
expect(imageTag.getAttribute(`src`)).toEqual(`test_image.jpg`)
expect(imageTag.getAttribute(`srcSet`)).toEqual(`some srcSet`)
expect(imageTag.getAttribute(`title`)).toEqual(`Title for the image`)
Expand All @@ -81,9 +159,9 @@ describe(`<Image />`, () => {
it(`should call onLoad and onError image events`, () => {
const onLoadMock = jest.fn()
const onErrorMock = jest.fn()
const imageTag = setup(true, onLoadMock, onErrorMock).querySelector(
const imageTag = setup(true, onLoadMock, onErrorMock).querySelectorAll(
`picture img`
)
)[1]
fireEvent.load(imageTag)
fireEvent.error(imageTag)

Expand Down
Loading