@@ -29,12 +29,36 @@ import type { ImageDTO } from 'services/api/types';
2929 * Gets the number of images per row in the gallery by grabbing their DOM elements.
3030 */
3131const getImagesPerRow = ( ) : number => {
32- const widthOfGalleryImage =
33- document . querySelector ( `.${ GALLERY_IMAGE_CLASS_NAME } ` ) ?. getBoundingClientRect ( ) . width ?? 1 ;
32+ const imageEl = document . querySelector ( `. ${ GALLERY_IMAGE_CLASS_NAME } ` ) ;
33+ const gridEl = document . querySelector ( `.${ GALLERY_GRID_CLASS_NAME } ` ) ;
3434
35- const widthOfGalleryGrid = document . querySelector ( `.${ GALLERY_GRID_CLASS_NAME } ` ) ?. getBoundingClientRect ( ) . width ?? 0 ;
35+ if ( ! imageEl || ! gridEl ) {
36+ return 0 ;
37+ }
38+ const container = gridEl . parentElement ;
39+ if ( ! container ) {
40+ return 0 ;
41+ }
42+
43+ const imageRect = imageEl . getBoundingClientRect ( ) ;
44+ const containerRect = container . getBoundingClientRect ( ) ;
45+
46+ // We need to account for the gap between images
47+ const gridElStyle = window . getComputedStyle ( gridEl ) ;
48+ const gap = parseFloat ( gridElStyle . gap ) ;
3649
37- const imagesPerRow = Math . round ( widthOfGalleryGrid / widthOfGalleryImage ) ;
50+ let imagesPerRow = 0 ;
51+ let spaceUsed = 0 ;
52+
53+ // Floating point precision can cause imagesPerRow to be 1 too small. Adding 1px to the container size fixes
54+ // this, without the possibility of accidentally adding an extra column.
55+ while ( spaceUsed + imageRect . width <= containerRect . width + 1 ) {
56+ imagesPerRow ++ ; // Increment the number of images
57+ spaceUsed += imageRect . width ; // Add image size to the used space
58+ if ( spaceUsed + gap <= containerRect . width ) {
59+ spaceUsed += gap ; // Add gap size to the used space after each image except after the last image
60+ }
61+ }
3862
3963 return imagesPerRow ;
4064} ;
0 commit comments