diff --git a/__test__/Gallery.test.js b/__test__/Gallery.test.js index 6a58eea..432f2f5 100644 --- a/__test__/Gallery.test.js +++ b/__test__/Gallery.test.js @@ -37,4 +37,15 @@ describe('Gallery', () => { wrapper = mount(); expect(columns).toBeCalledWith(1140); }); + + it('calls the callback when all images finish loading', () => { + const callback = jest.fn(); + wrapper = mount(); + let images = wrapper.find('img'); + images.forEach(node => { + node.simulate('load'); + }); + + expect(callback).toHaveBeenCalled(); + }); }); diff --git a/__test__/__snapshots__/Gallery.test.js.snap b/__test__/__snapshots__/Gallery.test.js.snap index 290171a..fbca1fd 100644 --- a/__test__/__snapshots__/Gallery.test.js.snap +++ b/__test__/__snapshots__/Gallery.test.js.snap @@ -328,6 +328,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="40673436833" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673436833_5fc1ab52fe_b.jpg" srcSet={ @@ -353,6 +354,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="47587238132" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238132_4683fdabb2_b.jpg" srcSet={ @@ -378,6 +380,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="32697497947" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497947_7d6dfaf5ec_b.jpg" srcSet={ @@ -403,6 +406,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="32697497647" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497647_31cd88c0b5_b.jpg" srcSet={ @@ -428,6 +432,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="47587238242" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238242_6776b8a582_b.jpg" srcSet={ @@ -453,6 +458,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="40673437163" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437163_703ffe416d_b.jpg" srcSet={ @@ -478,6 +484,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={332.64705882352945} key="47587238362" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238362_5d355937cb_b.jpg" srcSet={ @@ -503,6 +510,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={332.64705882352945} key="32697498187" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697498187_7a74849c76_b.jpg" srcSet={ @@ -528,6 +536,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={241.32762312633832} key="40673436913" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673436913_c48ac9e6d5_b.jpg" srcSet={ @@ -553,6 +562,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={241.32762312633832} key="40673437213" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437213_3480e88c8b_b.jpg" srcSet={ @@ -578,6 +588,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={241.32762312633832} key="47587238482" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238482_5ac51de790_b.jpg" srcSet={ @@ -603,6 +614,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={252.1252796420582} key="32697498227" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697498227_a3bc50aa6c_b.jpg" srcSet={ @@ -628,6 +640,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={252.1252796420582} key="40673437263" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437263_b03be98bae_b.jpg" srcSet={ @@ -653,6 +666,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={252.1252796420582} key="32697497717" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497717_1fb25b32be_b.jpg" srcSet={ @@ -678,6 +692,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="47587238552" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238552_cfce31cc10_b.jpg" srcSet={ @@ -703,6 +718,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="47640016631" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47640016631_cfffe28dd0_b.jpg" srcSet={ @@ -728,6 +744,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={250.44444444444446} key="47640017061" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47640017061_d6f554a175_b.jpg" srcSet={ @@ -753,6 +770,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={254.4018058690745} key="32697497787" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497787_ebd9165050_b.jpg" srcSet={ @@ -778,6 +796,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={254.4018058690745} key="40673437303" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437303_ec8b5a7246_b.jpg" srcSet={ @@ -803,6 +822,7 @@ exports[`Gallery it matches correct snapshot 1`] = ` height={254.4018058690745} key="46724351385" onClick={[Function]} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/46724351385_a6ff50ddda_b.jpg" srcSet={ @@ -1154,6 +1174,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="40673436833" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673436833_5fc1ab52fe_b.jpg" srcSet={ @@ -1181,6 +1202,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="47587238132" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238132_4683fdabb2_b.jpg" srcSet={ @@ -1208,6 +1230,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="32697497947" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497947_7d6dfaf5ec_b.jpg" srcSet={ @@ -1235,6 +1258,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="32697497647" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497647_31cd88c0b5_b.jpg" srcSet={ @@ -1262,6 +1286,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="47587238242" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238242_6776b8a582_b.jpg" srcSet={ @@ -1289,6 +1314,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="40673437163" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437163_703ffe416d_b.jpg" srcSet={ @@ -1316,6 +1342,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="47587238362" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238362_5d355937cb_b.jpg" srcSet={ @@ -1343,6 +1370,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={197.7} key="32697498187" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697498187_7a74849c76_b.jpg" srcSet={ @@ -1370,6 +1398,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="40673436913" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673436913_c48ac9e6d5_b.jpg" srcSet={ @@ -1397,6 +1426,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={225} key="40673437213" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437213_3480e88c8b_b.jpg" srcSet={ @@ -1424,6 +1454,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="47587238482" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238482_5ac51de790_b.jpg" srcSet={ @@ -1451,6 +1482,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="32697498227" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697498227_a3bc50aa6c_b.jpg" srcSet={ @@ -1478,6 +1510,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={255.6} key="40673437263" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437263_b03be98bae_b.jpg" srcSet={ @@ -1505,6 +1538,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="32697497717" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497717_1fb25b32be_b.jpg" srcSet={ @@ -1532,6 +1566,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="47587238552" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47587238552_cfce31cc10_b.jpg" srcSet={ @@ -1559,6 +1594,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="47640016631" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47640016631_cfffe28dd0_b.jpg" srcSet={ @@ -1586,6 +1622,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="47640017061" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/47640017061_d6f554a175_b.jpg" srcSet={ @@ -1613,6 +1650,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={166.2} key="32697497787" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/32697497787_ebd9165050_b.jpg" srcSet={ @@ -1640,6 +1678,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={560.9} key="40673437303" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/40673437303_ec8b5a7246_b.jpg" srcSet={ @@ -1667,6 +1706,7 @@ exports[`Gallery renders correctly with direction set to column 1`] = ` height={250.4} key="46724351385" onClick={null} + onLoad={[Function]} sizes="(min-width: 480px) 50vw, (min-width: 1024px) 33.3vw, 100vw" src="https://live.staticflickr.com/65535/46724351385_a6ff50ddda_b.jpg" srcSet={ diff --git a/examples/src/ExampleBasic.js b/examples/src/ExampleBasic.js index 1b258a3..020208e 100644 --- a/examples/src/ExampleBasic.js +++ b/examples/src/ExampleBasic.js @@ -1,11 +1,11 @@ import React from 'react'; import Gallery from 'react-photo-gallery'; -const ExampleBasic = ({photos, title, direction}) => { +const ExampleBasic = ({ photos, title, direction, onLoadCallback }) => { return (

{title}

- +
); } diff --git a/examples/src/app.js b/examples/src/app.js index db4872d..0436a0f 100644 --- a/examples/src/app.js +++ b/examples/src/app.js @@ -60,9 +60,12 @@ class App extends React.Component { render() { if (this.state.photos) { const width = this.state.width; + const onLoad = () => { + console.log('Finished Loading Images'); + } return (
- + diff --git a/src/Gallery.js b/src/Gallery.js index b5475d9..2f2a7d8 100644 --- a/src/Gallery.js +++ b/src/Gallery.js @@ -15,9 +15,11 @@ const Gallery = React.memo(function Gallery({ targetRowHeight, columns, renderImage, + onLoadCallback, }) { const [containerWidth, setContainerWidth] = useState(0); const galleryEl = useRef(null); + let loadedCount = 0; useLayoutEffect(() => { let animationFrameID = null; @@ -48,6 +50,13 @@ const Gallery = React.memo(function Gallery({ }); }; + const onImageLoaded = () => { + loadedCount++; + if (onLoadCallback && typeof onLoadCallback === 'function' && loadedCount === photos.length) { + onLoadCallback(); + } + }; + // no containerWidth until after first render with refs, skip calculations and render nothing if (!containerWidth) return
 
; // subtract 1 pixel because the browser may round up a pixel @@ -106,6 +115,7 @@ const Gallery = React.memo(function Gallery({ direction, onClick: onClick ? handleClick : null, photo, + onImageLoaded, }); })}
@@ -122,6 +132,7 @@ Gallery.propTypes = { limitNodeSearch: PropTypes.oneOfType([PropTypes.func, PropTypes.number]), margin: PropTypes.number, renderImage: PropTypes.func, + onLoadCallback: PropTypes.func, }; Gallery.defaultProps = { diff --git a/src/Photo.js b/src/Photo.js index 18e3d3f..03c52d6 100644 --- a/src/Photo.js +++ b/src/Photo.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; const imgWithClick = { cursor: 'pointer' }; -const Photo = ({ index, onClick, photo, margin, direction, top, left, key }) => { +const Photo = ({ index, onClick, photo, margin, direction, top, left, key, onImageLoaded }) => { const imgStyle = { margin: margin, display: 'block' }; if (direction === 'column') { imgStyle.position = 'absolute'; @@ -21,6 +21,7 @@ const Photo = ({ index, onClick, photo, margin, direction, top, left, key }) => style={onClick ? { ...imgStyle, ...imgWithClick } : imgStyle} {...photo} onClick={onClick ? handleClick : null} + onLoad={onImageLoaded ? onImageLoaded : null} /> ); }; @@ -52,6 +53,7 @@ Photo.propTypes = { } }, direction: PropTypes.string, + onImageLoaded: PropTypes.func, }; export default Photo;