Skip to content

Commit 4b9b6a1

Browse files
oolothwardpeet
andcommitted
feat(gatsby-image): Add gatsby-image/withIEPolyfill export with object-fit/position support (#12681)
## Description This PR will allow users who want `object-fit/object-position` support in IE to simply `import Img from "gatsby-image/withIEPolyfill"` instead of importing directly from `"gatsby-image"`. Please feel free to review the PR and let me know if the implementation can be improved. The `/withIEPolyfill` version of `gatsby-image` currently does the following: 1. Checks if the browser supports the `object-fit/position` CSS properties. a. If yes, no polyfill is loaded. b. If no, the `object-fit-images` polyfill is imported and called. 2. Wraps `gatsby-image` in a component that passes the new `objectFit` and `objectPosition` prop values to the polyfill implementation (which requires a weird `font-family` hack). ### New props To make the implementation simple, I've added new `objectFit` and `objectPosition` props that will needed to be used to pass the corresponding values to the polyfill. This is to avoid a scenario where a user attempts to set these values in a way we can't pass to the polyfill (e.g. via an external CSS stylesheet) and doesn't understand why the polyfill isn't working. Let me know if this API can be improved. ### Loading polyfill in /withIEPolyfill/index.js I opted to load the `object-fit-images` polyfill directly in `withIEPolyfill/index.js` rather than in `gatsby-browser.js`. If anyone knows of a better way to approach this, please let me know and feel free to make improvements. ### Polyfill repo has been archived I was surprised to see that the `object-fit-images` [repo](https://github.com/bfred-it/object-fit-images) has recently been archived by its owner. It still works, but if anyone is concerned about this or knows of a reliable alternative polyfill, please let me know. ### Docs to be updated once implementation is finalized Once we've settled on the API for this `/withIEPolyfills` component, a brief explanation will need to be added to the `gatsby-image` docs. I held off on adding one for now in case we end up changing the API. ## Related Issues Fixes #4021. Co-authored-by: Ward Peeters <[email protected]>
1 parent 29fec04 commit 4b9b6a1

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

packages/gatsby-image/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/*.js
2+
/withIEPolyfill/*.js
23
yarn.lock

packages/gatsby-image/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
},
99
"dependencies": {
1010
"@babel/runtime": "^7.0.0",
11+
"object-fit-images": "^3.2.4",
1112
"prop-types": "^15.6.1"
1213
},
1314
"devDependencies": {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { Component, createRef, forwardRef } from "react"
2+
import PropTypes from "prop-types"
3+
import Image from "../index"
4+
5+
class ImageWithIEPolyfill extends Component {
6+
imageRef = this.props.innerRef || createRef()
7+
8+
// Load object-fit/position polyfill if required (e.g. in IE)
9+
componentDidMount() {
10+
const testImg = document.createElement(`img`)
11+
if (
12+
typeof testImg.style.objectFit === `undefined` ||
13+
typeof testImg.style.objectPosition === `undefined`
14+
) {
15+
import(`object-fit-images`).then(({ default: ObjectFitImages }) =>
16+
ObjectFitImages(this.imageRef.current.imageRef.current)
17+
)
18+
}
19+
}
20+
21+
render() {
22+
const { objectFit, objectPosition, ...props } = this.props
23+
24+
return (
25+
<Image
26+
ref={this.imageRef}
27+
{...props}
28+
imgStyle={{
29+
...props.imgStyle,
30+
objectFit: objectFit,
31+
objectPosition: objectPosition,
32+
fontFamily: `"object-fit: ${objectFit}; object-position: ${objectPosition}"`,
33+
}}
34+
/>
35+
)
36+
}
37+
}
38+
39+
ImageWithIEPolyfill.propTypes = {
40+
objectFit: PropTypes.string,
41+
objectPosition: PropTypes.string,
42+
}
43+
44+
ImageWithIEPolyfill.defaultProps = {
45+
objectFit: `cover`,
46+
objectPosition: `50% 50%`,
47+
}
48+
49+
export default forwardRef((props, ref) => (
50+
<ImageWithIEPolyfill {...props} innerRef={ref} />
51+
))

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13148,6 +13148,11 @@ object-copy@^0.1.0:
1314813148
define-property "^0.2.5"
1314913149
kind-of "^3.0.3"
1315013150

13151+
object-fit-images@^3.2.4:
13152+
version "3.2.4"
13153+
resolved "https://registry.yarnpkg.com/object-fit-images/-/object-fit-images-3.2.4.tgz#6c299d38fdf207746e5d2d46c2877f6f25d15b52"
13154+
integrity sha512-G+7LzpYfTfqUyrZlfrou/PLLLAPNC52FTy5y1CBywX+1/FkxIloOyQXBmZ3Zxa2AWO+lMF0JTuvqbr7G5e5CWg==
13155+
1315113156
object-hash@^1.1.4:
1315213157
version "1.3.0"
1315313158
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2"

0 commit comments

Comments
 (0)