Skip to content

Instantly share code, notes, and snippets.

@iksi
Created March 11, 2020 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iksi/db54e1a60a41a312e8eb673e50d967aa to your computer and use it in GitHub Desktop.
Save iksi/db54e1a60a41a312e8eb673e50d967aa to your computer and use it in GitHub Desktop.
import React from 'react';
import PropTypes from 'prop-types';
const getSrcUrl = (url, width) => `${url}?w=${width}&fm=jpg&auto=format`;
const getSrcSet = (url, widths) => widths
.map((width) => `${getSrcUrl(url, width)} ${width}w`)
.join(', ');
export const Image = ({
alt,
caption,
height,
loading = 'lazy',
forceAspectRatio,
sizes = '100vw',
srcSetWidths = [160, 320, 640, 960, 1280, 1600],
url,
width,
}) => {
const aspectRatio = forceAspectRatio || width / height;
const props = {
alt: alt || '',
className: `image__content ${loading === 'lazy' ? 'js-lazy-image' : ''}`.trim(),
height,
loading,
sizes,
width,
};
const src = getSrcUrl(url, srcSetWidths[0]);
const srcSet = getSrcSet(url, srcSetWidths);
const srcProps = { src, srcSet };
const lazySrcProps = {
src: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
'data-src': src,
'data-srcset': srcSet,
};
return (
<figure className="image">
<div className="image__ratio" style={{ '--aspect-ratio': aspectRatio }}>
{/* eslint-disable-next-line jsx-a11y/alt-text */}
<img {...props} {...(loading === 'lazy' ? lazySrcProps : srcProps)} />
<If condition={loading === 'lazy'}>
<noscript>
{/* eslint-disable-next-line jsx-a11y/alt-text */}
<img {...props} {...srcProps} />
</noscript>
</If>
</div>
<If condition={caption}>
<figcaption className="image__caption">
{caption}
</figcaption>
</If>
</figure>
);
};
Image.propTypes = {
alt: PropTypes.string,
caption: PropTypes.string,
height: PropTypes.number.isRequired,
loading: PropTypes.oneOf(['eager', 'lazy']),
sizes: PropTypes.string,
url: PropTypes.string.isRequired,
forceAspectRatio: PropTypes.number,
srcSetWidths: PropTypes.array,
width: PropTypes.number.isRequired,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment