diff --git a/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx b/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx index 42a014e2b48ff..f93f00bcb03b0 100644 --- a/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx +++ b/packages/gatsby-plugin-image/src/components/gatsby-image.browser.tsx @@ -7,6 +7,7 @@ import React, { ImgHTMLAttributes, useState, RefObject, + CSSProperties, } from "react" import { getWrapperProps, @@ -26,7 +27,12 @@ export interface GatsbyImageProps alt: string as?: ElementType className?: string + imgClassName?: string image: IGatsbyImageData + imgStyle?: CSSProperties + backgroundColor?: string + objectFit?: CSSProperties["objectFit"] + objectPosition?: CSSProperties["objectPosition"] onLoad?: () => void onError?: () => void onStartLoad?: Function @@ -53,6 +59,7 @@ export const GatsbyImageHydrator: FunctionComponent = function onStartLoad, image, onLoad: customOnLoad, + backgroundColor, ...props }) { if (!image) { @@ -61,7 +68,7 @@ export const GatsbyImageHydrator: FunctionComponent = function } return null } - const { width, height, layout, images, backgroundColor } = image + const { width, height, layout, images } = image const root = useRef() const hydrated = useRef(false) @@ -188,6 +195,7 @@ export const GatsbyImageHydrator: FunctionComponent = function style={{ ...wStyle, ...style, + backgroundColor, }} className={`${wClass}${className ? ` ${className}` : ``}`} ref={root} diff --git a/packages/gatsby-plugin-image/src/components/gatsby-image.server.tsx b/packages/gatsby-plugin-image/src/components/gatsby-image.server.tsx index 2380201a602e0..0802f6a8ee8de 100644 --- a/packages/gatsby-plugin-image/src/components/gatsby-image.server.tsx +++ b/packages/gatsby-plugin-image/src/components/gatsby-image.server.tsx @@ -21,6 +21,11 @@ export const GatsbyImage: FunctionComponent = function GatsbyI style, image, loading = `lazy`, + imgClassName, + imgStyle, + backgroundColor, + objectFit, + objectPosition, ...props }) { if (!image) { @@ -35,7 +40,7 @@ export const GatsbyImage: FunctionComponent = function GatsbyI images, placeholder, sizes, - backgroundColor, + backgroundColor: placeholderBackgroundColor, } = image const { style: wStyle, className: wClass, ...wrapperProps } = getWrapperProps( @@ -73,6 +78,7 @@ export const GatsbyImage: FunctionComponent = function GatsbyI style={{ ...wStyle, ...style, + backgroundColor, }} className={`${wClass}${className ? ` ${className}` : ``}`} > @@ -84,7 +90,7 @@ export const GatsbyImage: FunctionComponent = function GatsbyI layout, width, height, - backgroundColor + placeholderBackgroundColor )} /> diff --git a/packages/gatsby-plugin-image/src/components/hooks.ts b/packages/gatsby-plugin-image/src/components/hooks.ts index 265d6d451b8cb..57d90730e4099 100644 --- a/packages/gatsby-plugin-image/src/components/hooks.ts +++ b/packages/gatsby-plugin-image/src/components/hooks.ts @@ -87,7 +87,8 @@ export function getMainProps( loading?: "eager" | "lazy", toggleLoaded?: any, cacheKey?: string, - ref?: any + ref?: any, + style: CSSProperties = {} ): MainImageProps { const onLoad: ReactEventHandler = function (e) { if (isLoaded) { @@ -115,31 +116,34 @@ export function getMainProps( } } + // fallback when it's not configured in gatsby-config. + if (!global.GATSBY___IMAGE) { + style = { + height: `100%`, + left: 0, + position: `absolute`, + top: 0, + transform: `translateZ(0)`, + transition: `opacity 250ms linear`, + width: `100%`, + willChange: `opacity`, + ...style, + } + } + const result = { ...images, loading, shouldLoad: isLoading, "data-main-image": ``, style: { + ...style, opacity: isLoaded ? 1 : 0, }, onLoad, ref, } - // fallback when it's not configured in gatsby-config. - if (!global.GATSBY___IMAGE) { - result.style.height = `100%` - result.style.left = 0 - result.style.position = `absolute` - result.style.top = 0 - result.style.transform = `translateZ(0)` - result.style.transition = `opacity 250ms linear` - result.style.width = `100%` - result.style.willChange = `opacity` - result.style.objectFit = `cover` - } - return result } diff --git a/packages/gatsby-plugin-image/src/components/lazy-hydrate.tsx b/packages/gatsby-plugin-image/src/components/lazy-hydrate.tsx index 775cd97bd88b9..91c289027af41 100644 --- a/packages/gatsby-plugin-image/src/components/lazy-hydrate.tsx +++ b/packages/gatsby-plugin-image/src/components/lazy-hydrate.tsx @@ -27,12 +27,24 @@ export function lazyHydrate( isLoaded, toggleIsLoaded, ref, + imgClassName, + imgStyle = {}, + objectPosition, + backgroundColor, + objectFit = `cover`, ...props }: LazyHydrateProps, root: MutableRefObject, hydrated: MutableRefObject ): (() => void) | null { - const { width, height, layout, images, placeholder, backgroundColor } = image + const { + width, + height, + layout, + images, + placeholder, + backgroundColor: wrapperBackgroundColor, + } = image if (!root.current) { return null @@ -47,6 +59,13 @@ export function lazyHydrate( const cacheKey = JSON.stringify(images) const hasLoaded = !hydrated.current && hasImageLoaded(cacheKey) + imgStyle = { + objectFit, + objectPosition, + backgroundColor, + ...imgStyle, + } + const component = ( {!hasLoaded && ( @@ -57,12 +76,13 @@ export function lazyHydrate( layout, width, height, - backgroundColor + wrapperBackgroundColor )} /> )} )} + className={imgClassName} {...getMainProps( isLoading, hasLoaded || isLoaded, @@ -70,7 +90,8 @@ export function lazyHydrate( loading, toggleIsLoaded, cacheKey, - ref + ref, + imgStyle )} /> diff --git a/packages/gatsby-plugin-image/src/components/static-image.server.tsx b/packages/gatsby-plugin-image/src/components/static-image.server.tsx index ea598e43f6fe9..d01678784ff63 100644 --- a/packages/gatsby-plugin-image/src/components/static-image.server.tsx +++ b/packages/gatsby-plugin-image/src/components/static-image.server.tsx @@ -16,13 +16,13 @@ export interface IStaticImageProps extends Omit { maxHeight?: number sizes?: string quality?: number - transformOptions: { + transformOptions?: { fit?: Fit } jpgOptions?: Record pngOptions?: Record webpOptions?: Record - blurredOptions: Record + blurredOptions?: Record } // These values are added by Babel. Do not add them manually @@ -38,6 +38,7 @@ export function _getStaticImage( src, __imageData: imageData, __error, + // We extract these because they're not meant to be passed-down to GatsbyImage /* eslint-disable @typescript-eslint/no-unused-vars */ width, maxWidth,