From 3b3650399008450ed3239c747d4740e17838078f Mon Sep 17 00:00:00 2001 From: Xiao Lin Date: Sun, 30 Jul 2023 00:22:22 -0700 Subject: [PATCH] [#655] Fixes slides overlap when there are only 2 images (#751) --- README.md | 3 +- src/components/ImageGallery.jsx | 77 ++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 39523dab..61cbad44 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,6 @@ class MyGallery extends React.Component { - `srcSet` - image srcset (html5 attribute) - `sizes` - image sizes (html5 attribute) - `bulletClass` - extra class for the bullet of the item - - `bulletOnClick` - `callback({item, itemIndex, currentIndex})` - - A function that will be called upon bullet click. - `infinite`: Boolean, default `true` - infinite sliding - `lazyLoad`: Boolean, default `false` @@ -144,6 +142,7 @@ class MyGallery extends React.Component { - `onThumbnailError`: Function, `callback(event)` - overrides onErrorImage - `onThumbnailClick`: Function, `callback(event, index)` +- `onBulletClick`: Function, `callback(event, index)` - `onImageLoad`: Function, `callback(event)` - `onSlide`: Function, `callback(currentIndex)` - `onBeforeSlide`: Function, `callback(nextIndex)` diff --git a/src/components/ImageGallery.jsx b/src/components/ImageGallery.jsx index 2bb23116..bfe79b72 100644 --- a/src/components/ImageGallery.jsx +++ b/src/components/ImageGallery.jsx @@ -244,18 +244,39 @@ class ImageGallery extends React.Component { } onThumbnailClick(event, index) { - const { onThumbnailClick } = this.props; + const { onThumbnailClick, items } = this.props; const { currentIndex } = this.state; // blur element to remove outline cause by focus event.target.parentNode.parentNode.blur(); if (currentIndex !== index) { - this.slideToIndex(index, event); + if (items.length === 2) { + this.slideToIndexWithStyleReset(index, event); + } else { + this.slideToIndex(index, event); + } } if (onThumbnailClick) { onThumbnailClick(event, index); } } + onBulletClick = (event, index) => { + const { onBulletClick, items } = this.props; + const { currentIndex } = this.state; + // blur element to remove outline caused by focus + event.target.blur(); + if (currentIndex !== index) { + if (items.length === 2) { + this.slideToIndexWithStyleReset(index, event); + } else { + this.slideToIndex(index, event); + } + } + if (onBulletClick) { + onBulletClick(event, index); + } + }; + onThumbnailMouseOver(event, index) { if (this.thumbnailMouseOverTimer) { window.clearTimeout(this.thumbnailMouseOverTimer); @@ -628,15 +649,6 @@ class ImageGallery extends React.Component { } if (showBullets) { - // generate bullet elements and store them in array - const bulletOnClick = (event) => { - if (item.bulletOnClick) { - item.bulletOnClick({ item, itemIndex: index, currentIndex }); - } - // blur element to remove outline caused by focus - event.target.blur(); - return this.slideToIndex.call(this, index, event); - }; const igBulletClass = clsx("image-gallery-bullet", item.bulletClass, { active: currentIndex === index, }); @@ -645,7 +657,7 @@ class ImageGallery extends React.Component { type="button" key={`bullet-${index}`} className={igBulletClass} - onClick={bulletOnClick} + onClick={(event) => this.onBulletClick(event, index)} aria-pressed={currentIndex === index ? "true" : "false"} aria-label={`Go to Slide ${index + 1}`} /> @@ -1199,34 +1211,39 @@ class ImageGallery extends React.Component { } slideTo(event, direction) { - const { currentIndex, currentSlideOffset, isTransitioning } = this.state; + const { currentIndex, isTransitioning } = this.state; const { items } = this.props; const nextIndex = currentIndex + (direction === "left" ? -1 : 1); if (isTransitioning) return; if (items.length === 2) { - /* - When there are only 2 slides fake a tiny swipe to get the slides - on the correct side for transitioning - */ - this.setState( - { - // this will reset once index changes - currentSlideOffset: - currentSlideOffset + (direction === "left" ? 0.001 : -0.001), - slideStyle: { transition: "none" }, // move the slide over instantly - }, - () => { - // add 25ms timeout to avoid delay in moving slides over - window.setTimeout(() => this.slideToIndex(nextIndex, event), 25); - } - ); + this.slideToIndexWithStyleReset(nextIndex, event); } else { this.slideToIndex(nextIndex, event); } } + slideToIndexWithStyleReset(nextIndex, event) { + /* + When there are only 2 slides fake a tiny swipe to get the slides + on the correct side for transitioning + */ + const { currentIndex, currentSlideOffset } = this.state; + this.setState( + { + // this will reset once index changes + currentSlideOffset: + currentSlideOffset + (currentIndex > nextIndex ? 0.001 : -0.001), + slideStyle: { transition: "none" }, // move the slide over instantly + }, + () => { + // add 25ms timeout to avoid delay in moving slides over + window.setTimeout(() => this.slideToIndex(nextIndex, event), 25); + } + ); + } + handleThumbnailMouseOver(event, index) { const { slideOnThumbnailOver } = this.props; if (slideOnThumbnailOver) this.onThumbnailMouseOver(event, index); @@ -1626,6 +1643,7 @@ ImageGallery.propTypes = { onTouchStart: func, onMouseOver: func, onMouseLeave: func, + onBulletClick: func, onThumbnailError: func, onThumbnailClick: func, renderCustomControls: func, @@ -1682,6 +1700,7 @@ ImageGallery.defaultProps = { onTouchStart: null, onMouseOver: null, onMouseLeave: null, + onBulletClick: null, onThumbnailError: null, onThumbnailClick: null, renderCustomControls: null,