All files / src/Image Image.js

0% Statements 0/17
0% Branches 0/16
0% Functions 0/1
0% Lines 0/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93                                                                                                                                                                                         
import React, { Component } from 'preact';
import PropTypes from 'prop-types';
import { StyledImageWrapper, StyledImage } from './styles';
 
/**
 * Progressive Image Loading with a blur effect option to reduce the page load time
 *
 * @example ./../../docs/components/Image.md
 */
class Image extends Component {
    static propTypes = {
        /**
         * Custom styles
         */
        style: PropTypes.string,
 
        /**
         * Gets called when the user clicks on the button
         *
         * @param {SyntheticEvent} event The react `SyntheticEvent`
         */
        onClick: PropTypes.func,
    };
    handleImageLoaded = () => {
        this.setState({
            placeholderHeight: 0,
            placeholderWidth: 0,
            imageLoaded: true,
        });
    };
    handleImageErrored = () => {
        // TODO - Should re-fetch the image
    };
    renderResponsiveImages = (images = []) => {
        return images.map(image => {
            return <source srcset={image.src} media={image.media} />;
        });
    };
    placeholderOnLoad = element => {
        if (!this.state.imageLoaded) {
            this.setState({
                placeholderHeight: element.target.offsetHeight,
                placeholderWidth: element.target.offsetWidth,
            });
        }
    };
    renderPlaceholder = placeholder => {
        if (placeholder) {
            return (
                <StyledImage
                    src={placeholder}
                    style={`
				position:absolute;
				top: 0;
				left: 0;
				opacity: ${this.state.imageLoaded ? '0' : '1'};
				filter: blur(5px);
				transform: scale(1);
				transition: opacity 1s linear;
			`}
                    handleImageLoaded={this.placeholderOnLoad}
                />
            );
        }
        return '';
    };
    render() {
        const { responsive, placeholder = '', className, inline } = this.props;
        const { placeholderHeight = 0, placeholderWidth = 0 } = this.state;
        return (
            <StyledImageWrapper inline={inline} className={className}>
                <div
                    style={{
                        height: placeholderHeight + 'px',
                        width: placeholderWidth + 'px',
                    }}
                />
                <picture>
                    {this.renderResponsiveImages(responsive)}
                    <StyledImage
                        {...this.props}
                        handleImageLoaded={this.handleImageLoaded}
                        handleImageErrored={this.handleImageErrored}
                    />
                </picture>
                {this.renderPlaceholder(placeholder)}
            </StyledImageWrapper>
        );
    }
}
 
export default Image;