UNPKG

gatsby-plugin-image

Version:

Adding responsive images to your site while maintaining high performance scores can be difficult to do manually. The Gatsby Image plugin handles the hard parts of producing images in multiple sizes and formats for you!

3 lines (2 loc) 17.2 kB
import e,{Fragment as t,memo as a,createElement as i,useRef as s,useMemo as r,useEffect as n,useLayoutEffect as o}from"react";import l from"camelcase";import*as d from"prop-types";import c from"prop-types";function h(){return h=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var i in a)Object.prototype.hasOwnProperty.call(a,i)&&(e[i]=a[i])}return e},h.apply(this,arguments)}function u(e,t){if(null==e)return{};var a,i,s={},r=Object.keys(e);for(i=0;i<r.length;i++)t.indexOf(a=r[i])>=0||(s[a]=e[a]);return s}const g=[.25,.5,1,2],p=[750,1080,1366,1920],m=[320,654,768,1024,1366,1600,1920,2048,2560,3440,3840,4096],f=800,w=800,y=4/3,b=e=>console.warn(e),v=(e,t)=>e-t,E=(e,t)=>{switch(t){case"constrained":return`(min-width: ${e}px) ${e}px, 100vw`;case"fixed":return`${e}px`;case"fullWidth":return"100vw";default:return}},k=e=>e.map(e=>`${e.src} ${e.width}w`).join(",\n");function S(e){const t=e.lastIndexOf(".");if(-1!==t){const a=e.slice(t+1);if("jpeg"===a)return"jpg";if(3===a.length||4===a.length)return a}}function M(e){let{layout:t="constrained",width:a,height:i,sourceMetadata:s,breakpoints:r,aspectRatio:n,formats:o=["auto","webp"]}=e;return o=o.map(e=>e.toLowerCase()),t=l(t),a&&i?h({},e,{formats:o,layout:t,aspectRatio:a/i}):(s.width&&s.height&&!n&&(n=s.width/s.height),"fullWidth"===t?(a=a||s.width||r[r.length-1],i=i||Math.round(a/(n||y))):(a||(a=i&&n?i*n:s.width?s.width:i?Math.round(i/y):w),n&&!i?i=Math.round(a/n):n||(n=a/i)),h({},e,{width:a,height:i,aspectRatio:n,layout:t,formats:o}))}function N(e,t=20){var a;e=M(e);const{generateImageSource:i,filename:s,aspectRatio:r}=e;return null==(a=i(s,t,Math.round(t/r),e.sourceMetadata.format||"jpg",e.fit,e.options))?void 0:a.src}function $(e){e=M(e);let{pluginName:t,sourceMetadata:a,generateImageSource:i,layout:s,fit:r,options:n,width:o,height:l,filename:d,reporter:c={warn:b},backgroundColor:u,placeholderURL:m}=e;if(t||c.warn('[gatsby-plugin-image] "generateImageData" was not passed a plugin name'),"function"!=typeof i)throw new Error("generateImageSource must be a function");var f;a&&(a.width||a.height)?a.format||(a.format=S(d)):a={width:o,height:l,format:(null==(f=a)?void 0:f.format)||S(d)||"auto"};const y=new Set(e.formats);(0===y.size||y.has("auto")||y.has(""))&&(y.delete("auto"),y.delete(""),y.add(a.format)),y.has("jpg")&&y.has("png")&&(c.warn(`[${t}] Specifying both 'jpg' and 'png' formats is not supported. Using 'auto' instead`),y.delete("jpg"===a.format?"png":"jpg"));const v=function(e){const{width:t,height:a,filename:i,layout:s="constrained",sourceMetadata:r,reporter:n={warn:b},breakpoints:o=p}=e,l=Object.entries({width:t,height:a}).filter(([e,t])=>"number"==typeof t&&t<1);if(l.length)throw new Error(`Specified dimensions for images must be positive numbers (> 0). Problem dimensions you have are ${l.map(e=>e.join(": ")).join(", ")}`);return"fixed"===s?function({filename:e,sourceMetadata:t,width:a,height:i,fit:s="cover",outputPixelDensities:r=g,reporter:n={warn:b}}){let o=t.width/t.height;const l=I(r);if(a&&i){const e=j(t,{width:a,height:i,fit:s});a=e.width,i=e.height,o=e.aspectRatio}a?i||(i=Math.round(a/o)):a=i?Math.round(i*o):w;const d=a;if(t.width<a||t.height<i){const s=t.width<a?"width":"height";n.warn(`\nThe requested ${s} "${"width"===s?a:i}px" for the image ${e} was larger than the actual image ${s} of ${t[s]}px. If possible, replace the current image with a larger one.`),"width"===s?(a=t.width,i=Math.round(a/o)):a=(i=t.height)*o}return{sizes:l.filter(e=>e>=1).map(e=>Math.round(e*a)).filter(e=>e<=t.width),aspectRatio:o,presentationWidth:d,presentationHeight:Math.round(d/o),unscaledWidth:a}}(e):"constrained"===s?x(e):"fullWidth"===s?x(h({breakpoints:o},e)):(n.warn(`No valid layout was provided for the image at ${i}. Valid image layouts are fixed, fullWidth, and constrained. Found ${s}`),{sizes:[r.width],presentationWidth:r.width,presentationHeight:r.height,aspectRatio:r.width/r.height,unscaledWidth:r.width})}(h({},e,{sourceMetadata:a})),N={sources:[]};let $=e.sizes;$||($=E(v.presentationWidth,s)),y.forEach(e=>{const a=v.sizes.map(a=>{const s=i(d,a,Math.round(a/v.aspectRatio),e,r,n);if(null!=s&&s.width&&s.height&&s.src&&s.format)return s;c.warn(`[${t}] The resolver for image ${d} returned an invalid value.`)}).filter(Boolean);if("jpg"===e||"png"===e||"auto"===e){const e=a.find(e=>e.width===v.unscaledWidth)||a[0];e&&(N.fallback={src:e.src,srcSet:k(a),sizes:$})}else{var s;null==(s=N.sources)||s.push({srcSet:k(a),sizes:$,type:`image/${e}`})}});const L={images:N,layout:s,backgroundColor:u};switch(m&&(L.placeholder={fallback:m}),s){case"fixed":L.width=v.presentationWidth,L.height=v.presentationHeight;break;case"fullWidth":L.width=1,L.height=1/v.aspectRatio;break;case"constrained":L.width=e.width||v.presentationWidth||1,L.height=(L.width||1)/v.aspectRatio}return L}const I=e=>Array.from(new Set([1,...e])).sort(v);function x({sourceMetadata:e,width:t,height:a,fit:i="cover",outputPixelDensities:s=g,breakpoints:r,layout:n}){let o,l=e.width/e.height;const d=I(s);if(t&&a){const s=j(e,{width:t,height:a,fit:i});t=s.width,a=s.height,l=s.aspectRatio}t=t&&Math.min(t,e.width),a=a&&Math.min(a,e.height),t||a||(a=(t=Math.min(f,e.width))/l),t||(t=a*l);const c=t;return(e.width<t||e.height<a)&&(t=e.width,a=e.height),t=Math.round(t),(null==r?void 0:r.length)>0?(o=r.filter(t=>t<=e.width),o.length<r.length&&!o.includes(e.width)&&o.push(e.width)):(o=d.map(e=>Math.round(e*t)),o=o.filter(t=>t<=e.width)),"constrained"!==n||o.includes(t)||o.push(t),o=o.sort(v),{sizes:o,aspectRatio:l,presentationWidth:c,presentationHeight:Math.round(c/l),unscaledWidth:t}}function j(e,t){const a=e.width/e.height;let i=t.width,s=t.height;switch(t.fit){case"fill":i=t.width?t.width:e.width,s=t.height?t.height:e.height;break;case"inside":{const e=t.width?t.width:Number.MAX_SAFE_INTEGER,r=t.height?t.height:Number.MAX_SAFE_INTEGER;i=Math.min(e,Math.round(r*a)),s=Math.min(r,Math.round(e/a));break}case"outside":{const e=t.width?t.width:0,r=t.height?t.height:0;i=Math.max(e,Math.round(r*a)),s=Math.max(r,Math.round(e/a));break}default:t.width&&!t.height&&(i=t.width,s=Math.round(t.width/a)),t.height&&!t.width&&(i=Math.round(t.height*a),s=t.height)}return{width:i,height:s,aspectRatio:i/s}}const L=["baseUrl","urlBuilder","sourceWidth","sourceHeight","pluginName","formats","breakpoints","options"],T=["images","placeholder"],W=()=>"undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;function R(){return"undefined"!=typeof GATSBY___IMAGE&&GATSBY___IMAGE}const _=e=>{var t;return(e=>{var t,a;return Boolean(null==e||null==(t=e.images)||null==(a=t.fallback)?void 0:a.src)})(e)?e:(e=>Boolean(null==e?void 0:e.gatsbyImageData))(e)?e.gatsbyImageData:(e=>Boolean(null==e?void 0:e.gatsbyImage))(e)?e.gatsbyImage:null==e||null==(t=e.childImageSharp)?void 0:t.gatsbyImageData},C=e=>{var t,a,i;return null==(t=_(e))||null==(a=t.images)||null==(i=a.fallback)?void 0:i.src},O=e=>{var t,a,i;return null==(t=_(e))||null==(a=t.images)||null==(i=a.fallback)?void 0:i.srcSet};function z(e,t,a){const i={};let s="gatsby-image-wrapper";return R()||(i.position="relative",i.overflow="hidden"),"fixed"===a?(i.width=e,i.height=t):"constrained"===a&&(R()||(i.display="inline-block",i.verticalAlign="top"),s="gatsby-image-wrapper gatsby-image-wrapper-constrained"),{className:s,"data-gatsby-image-wrapper":"",style:i}}function D(e){var t;let{baseUrl:a,urlBuilder:i,sourceWidth:s,sourceHeight:r,pluginName:n="getImageData",formats:o=["auto"],breakpoints:l,options:d}=e,c=u(e,L);return null!=(t=l)&&t.length||"fullWidth"!==c.layout&&"FULL_WIDTH"!==c.layout||(l=m),$(h({},c,{pluginName:n,generateImageSource:(e,t,a,s)=>({width:t,height:a,format:s,src:i({baseUrl:e,width:t,height:a,options:d,format:s})}),filename:a,formats:o,breakpoints:l,sourceMetadata:{width:s,height:r,format:"auto"}}))}function P(e,t,a,i,s={}){return R()||(s=h({height:"100%",left:0,position:"absolute",top:0,transform:"translateZ(0)",transition:"opacity 250ms linear",width:"100%",willChange:"opacity"},s)),h({},a,{loading:i,shouldLoad:e,"data-main-image":"",style:h({},s,{opacity:t?1:0})})}function A(e,t,a,i,s,r,n,o){const l={};r&&(l.backgroundColor=r,"fixed"===a?(l.width=i,l.height=s,l.backgroundColor=r,l.position="relative"):("constrained"===a||"fullWidth"===a)&&(l.position="absolute",l.top=0,l.left=0,l.bottom=0,l.right=0)),n&&(l.objectFit=n),o&&(l.objectPosition=o);const d=h({},e,{"aria-hidden":!0,"data-placeholder-image":"",style:h({opacity:t?0:1,transition:"opacity 500ms linear"},l)});return R()||(d.style={height:"100%",left:0,position:"absolute",top:0,width:"100%"}),d}function q(e,t){const{images:a,placeholder:i}=e,s=h({},u(e,T),{images:h({},a,{sources:[]}),placeholder:i&&h({},i,{sources:[]})});var r;return t.forEach(({media:t,image:a})=>{t?(a.layout!==e.layout&&"development"===process.env.NODE_ENV&&console.warn(`[gatsby-plugin-image] Mismatched image layout: expected "${e.layout}" but received "${a.layout}". All art-directed images use the same layout as the default image`),s.images.sources.push(...a.images.sources.map(e=>h({},e,{media:t})),{media:t,srcSet:a.images.fallback.srcSet}),s.placeholder&&s.placeholder.sources.push({media:t,srcSet:a.placeholder.fallback})):"development"===process.env.NODE_ENV&&console.warn("[gatsby-plugin-image] All art-directed images passed to must have a value set for `media`. Skipping.")}),s.images.sources.push(...a.sources),null!=i&&i.sources&&(null==(r=s.placeholder)||r.sources.push(...i.sources)),s}const H=["children"],F=function({layout:t,width:a,height:i}){return"fullWidth"===t?e.createElement("div",{"aria-hidden":!0,style:{paddingTop:i/a*100+"%"}}):"constrained"===t?e.createElement("div",{style:{maxWidth:a,display:"block"}},e.createElement("img",{alt:"",role:"presentation","aria-hidden":"true",src:`data:image/svg+xml;charset=utf-8,%3Csvg%20height='${i}'%20width='${a}'%20xmlns='http://www.w3.org/2000/svg'%20version='1.1'%3E%3C/svg%3E`,style:{maxWidth:"100%",display:"block",position:"static"}})):null},G=function(a){let{children:i}=a,s=u(a,H);return e.createElement(t,null,e.createElement(F,h({},s)),i,null)},V=["src","srcSet","loading","alt","shouldLoad"],B=["fallback","sources","shouldLoad"],U=function(t){let{src:a,srcSet:i,loading:s,alt:r="",shouldLoad:n}=t,o=u(t,V);return e.createElement("img",h({},o,{decoding:"async",loading:s,src:n?a:void 0,"data-src":n?void 0:a,srcSet:n?i:void 0,"data-srcset":n?void 0:i,alt:r}))},Y=function(t){let{fallback:a,sources:i=[],shouldLoad:s=!0}=t,r=u(t,B);const n=r.sizes||(null==a?void 0:a.sizes),o=e.createElement(U,h({},r,a,{sizes:n,shouldLoad:s}));return i.length?e.createElement("picture",null,i.map(({media:t,srcSet:a,type:i})=>e.createElement("source",{key:`${t}-${i}-${a}`,type:i,media:t,srcSet:s?a:void 0,"data-srcset":s?void 0:a,sizes:n})),o):o};var X;U.propTypes={src:d.string.isRequired,alt:d.string.isRequired,sizes:d.string,srcSet:d.string,shouldLoad:d.bool},Y.displayName="Picture",Y.propTypes={alt:d.string.isRequired,shouldLoad:d.bool,fallback:d.exact({src:d.string.isRequired,srcSet:d.string,sizes:d.string}),sources:d.arrayOf(d.oneOfType([d.exact({media:d.string.isRequired,type:d.string,sizes:d.string,srcSet:d.string.isRequired}),d.exact({media:d.string,type:d.string.isRequired,sizes:d.string,srcSet:d.string.isRequired})]))};const J=["fallback"],Z=function(t){let{fallback:a}=t,i=u(t,J);return a?e.createElement(Y,h({},i,{fallback:{src:a},"aria-hidden":!0,alt:""})):e.createElement("div",h({},i))};Z.displayName="Placeholder",Z.propTypes={fallback:d.string,sources:null==(X=Y.propTypes)?void 0:X.sources,alt:function(e,t,a){return e[t]?new Error(`Invalid prop \`${t}\` supplied to \`${a}\`. Validation failed.`):null}};const K=function(t){return e.createElement(e.Fragment,null,e.createElement(Y,h({},t)),e.createElement("noscript",null,e.createElement(Y,h({},t,{shouldLoad:!0}))))};K.displayName="MainImage",K.propTypes=Y.propTypes;const Q=["as","className","class","style","image","loading","imgClassName","imgStyle","backgroundColor","objectFit","objectPosition"],ee=["style","className"],te=e=>e.replace(/\n/g,""),ae=(e,t,a,...i)=>e.alt||""===e.alt?c.string(e,t,a,...i):new Error(`The "alt" prop is required in ${a}. If the image is purely presentational then pass an empty string: e.g. alt="". Learn more: https://a11y-style-guide.com/style-guide/section-media.html`),ie={image:c.object.isRequired,alt:ae},se=["as","image","style","backgroundColor","className","class","onStartLoad","onLoad","onError"],re=["style","className"],ne=new Set;let oe,le;const de=function(e){let{as:t="div",image:a,style:l,backgroundColor:d,className:c,class:g,onStartLoad:p,onLoad:m,onError:f}=e,w=u(e,se);const{width:y,height:b,layout:v}=a,E=z(y,b,v),{style:k,className:S}=E,M=u(E,re),N=s(),$=r(()=>JSON.stringify(a.images),[a.images]);g&&(c=g);const I=function(e,t,a){let i="";return"fullWidth"===e&&(i=`<div aria-hidden="true" style="padding-top: ${a/t*100}%;"></div>`),"constrained"===e&&(i=`<div style="max-width: ${t}px; display: block;"><img alt="" role="presentation" aria-hidden="true" src="data:image/svg+xml;charset=utf-8,%3Csvg%20height='${a}'%20width='${t}'%20xmlns='http://www.w3.org/2000/svg'%20version='1.1'%3E%3C/svg%3E" style="max-width: 100%; display: block; position: static;"></div>`),i}(v,y,b);return n(()=>{oe||(oe=import("./lazy-hydrate-62277b8c.js").then(({renderImageToString:e,swapPlaceholderImage:t})=>(le=e,{renderImageToString:e,swapPlaceholderImage:t})));const e=N.current.querySelector("[data-gatsby-image-ssr]");if(e&&W())return e.complete?(null==p||p({wasCached:!0}),null==m||m({wasCached:!0}),setTimeout(()=>{e.removeAttribute("data-gatsby-image-ssr")},0)):(null==p||p({wasCached:!0}),e.addEventListener("load",function t(){e.removeEventListener("load",t),null==m||m({wasCached:!0}),setTimeout(()=>{e.removeAttribute("data-gatsby-image-ssr")},0)})),void ne.add($);if(le&&ne.has($))return;let t,i;return oe.then(({renderImageToString:e,swapPlaceholderImage:s})=>{N.current&&(N.current.innerHTML=e(h({isLoading:!0,isLoaded:ne.has($),image:a},w)),ne.has($)||(t=requestAnimationFrame(()=>{N.current&&(i=s(N.current,$,ne,l,p,m,f))})))}),()=>{t&&cancelAnimationFrame(t),i&&i()}},[a]),o(()=>{ne.has($)&&le&&(N.current.innerHTML=le(h({isLoading:ne.has($),isLoaded:ne.has($),image:a},w)),null==p||p({wasCached:!0}),null==m||m({wasCached:!0}))},[a]),i(t,h({},M,{style:h({},k,l,{backgroundColor:d}),className:`${S}${c?` ${c}`:""}`,ref:N,dangerouslySetInnerHTML:{__html:I},suppressHydrationWarning:!0}))},ce=a(function(e){return e.image?(R()||"development"!==process.env.NODE_ENV||console.warn('[gatsby-plugin-image] You\'re missing out on some cool performance features. Please add "gatsby-plugin-image" to your gatsby-config.js'),i(de,e)):("development"===process.env.NODE_ENV&&console.warn("[gatsby-plugin-image] Missing image prop"),null)});ce.propTypes=ie,ce.displayName="GatsbyImage";const he=["src","__imageData","__error","width","height","aspectRatio","tracedSVGOptions","placeholder","formats","quality","transformOptions","jpgOptions","pngOptions","webpOptions","avifOptions","blurredOptions","breakpoints","outputPixelDensities"];function ue(t){return function(a){let{src:i,__imageData:s,__error:r}=a,n=u(a,he);return r&&console.warn(r),s?e.createElement(t,h({image:s},n)):(console.warn("Image not loaded",i),r||"development"!==process.env.NODE_ENV||console.warn('Please ensure that "gatsby-plugin-image" is included in the plugins array in gatsby-config.js, and that your version of gatsby is at least 2.24.78'),null)}}const ge=ue(function(t){let{as:a="div",className:i,class:s,style:r,image:n,loading:o="lazy",imgClassName:l,imgStyle:d,backgroundColor:c,objectFit:g,objectPosition:p}=t,m=u(t,Q);if(!n)return console.warn("[gatsby-plugin-image] Missing image prop"),null;s&&(i=s),d=h({objectFit:g,objectPosition:p,backgroundColor:c},d);const{width:f,height:w,layout:y,images:b,placeholder:v,backgroundColor:E}=n,k=z(f,w,y),{style:S,className:M}=k,N=u(k,ee),$={fallback:void 0,sources:[]};return b.fallback&&($.fallback=h({},b.fallback,{srcSet:b.fallback.srcSet?te(b.fallback.srcSet):void 0})),b.sources&&($.sources=b.sources.map(e=>h({},e,{srcSet:te(e.srcSet)}))),e.createElement(a,h({},N,{style:h({},S,r,{backgroundColor:c}),className:`${M}${i?` ${i}`:""}`}),e.createElement(G,{layout:y,width:f,height:w},e.createElement(Z,h({},A(v,!1,y,f,w,E,g,p))),e.createElement(K,h({"data-gatsby-image-ssr":"",className:l},m,P("eager"===o,!1,$,o,d)))))}),pe=(e,t,...a)=>"fullWidth"!==e.layout||"width"!==t&&"height"!==t||!e[t]?c.number(e,t,...a):new Error(`"${t}" ${e[t]} may not be passed when layout is fullWidth.`),me=new Set(["fixed","fullWidth","constrained"]),fe={src:c.string.isRequired,alt:ae,width:pe,height:pe,sizes:c.string,layout:e=>{if(void 0!==e.layout&&!me.has(e.layout))return new Error(`Invalid value ${e.layout}" provided for prop "layout". Defaulting to "constrained". Valid values are "fixed", "fullWidth" or "constrained".`)}};ge.displayName="StaticImage",ge.propTypes=fe;const we=ue(ce);we.displayName="StaticImage",we.propTypes=fe;export{ce as G,G as L,K as M,Z as P,we as S,u as _,h as a,P as b,_ as c,C as d,O as e,D as f,A as g,W as h,$ as i,N as j,q as w}; //# sourceMappingURL=index.browser-006c3456.js.map