All files Gallery.js

89.47% Statements 34/38
80% Branches 20/25
87.5% Functions 7/8
90.91% Lines 30/33
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 94 95 96 97 98 99 100 101 102                      5x             5x     1x     1x 1x                 10x   10x 5x   5x 5x     5x 4x 4x 4x 4x   5x 5x     5x 4x 4x   5x 1x 1x 1x   5x   6x   35x 35x                                     1x                 1x            
import React from 'react';
import PropTypes from 'prop-types';
import ResizeObserver from 'resize-observer-polyfill';
import Photo, { photoPropType } from './Photo';
import { computeSizes, computeSizesColumns } from './utils';
 
class Gallery extends React.Component {
  state = {
    containerWidth: 0,
  };
  componentDidMount() {
    this.observer = new ResizeObserver(entries => {
      // only do something if width changes
      const newWidth = entries[0].contentRect.width;
      if (this.state.containerWidth !== newWidth) {
        this.setState({ containerWidth: Math.floor(newWidth) });
      }
    });
    this.observer.observe(this._gallery);
  }
  componentWillUnmount() {
    this.observer.disconnect();
  }
  handleClick = (event, { index }) => {
    const { photos, onClick } = this.props;
    onClick(event, {
      index,
      photo: photos[index],
      previous: photos[index - 1] || null,
      next: photos[index + 1] || null,
    });
  };
 
  render() {
    const containerWidth = this.state.containerWidth;
    // no containerWidth until after first render with refs, skip calculations and render nothing
    if (!containerWidth) return <div ref={c => (this._gallery = c)} />;
    const { ImageComponent = Photo } = this.props;
    // subtract 1 pixel because the browser may round up a pixel
    const { margin, onClick, direction } = this.props;
    let { columns } = this.props;
 
    // set default breakpoints if user doesn't specify columns prop
    if (columns === undefined) {
      columns = 1;
      Eif (containerWidth >= 500) columns = 2;
      if (containerWidth >= 900) columns = 3;
      Iif (containerWidth >= 1500) columns = 4;
    }
    const photos = this.props.photos;
    const width = containerWidth - 1;
    let galleryStyle, thumbs;
 
    if (direction === 'row') {
      galleryStyle = { display: 'flex', flexWrap: 'wrap', flexDirection: 'row' };
      thumbs = computeSizes({ width, columns, margin, photos });
    }
    if (direction === 'column') {
      galleryStyle = { position: 'relative' };
      thumbs = computeSizesColumns({ width, columns, margin, photos });
      galleryStyle.height = thumbs[thumbs.length - 1].containerHeight;
    }
    return (
      <div className="react-photo-gallery--gallery">
        <div ref={c => (this._gallery = c)} style={galleryStyle}>
          {thumbs.map((photo, index) => {
            const { left, top, containerHeight, ...rest } = photo;
            return (
              <ImageComponent
                key={photo.key || photo.src}
                margin={margin}
                index={index}
                photo={rest}
                direction={direction}
                left={left}
                top={top}
                onClick={onClick ? this.handleClick : null}
              />
            );
          })}
        </div>
      </div>
    );
  }
}
 
Gallery.propTypes = {
  photos: PropTypes.arrayOf(photoPropType).isRequired,
  direction: PropTypes.string,
  onClick: PropTypes.func,
  columns: PropTypes.number,
  margin: PropTypes.number,
  ImageComponent: PropTypes.func,
};
 
Gallery.defaultProps = {
  margin: 2,
  direction: 'row',
};
 
export default Gallery;