Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-gallery-carousel",
"version": "0.3.0",
"version": "0.4.0",
"description": "Mobile-friendly Carousel with batteries included (supporting touch, mouse emulation, lazy loading, thumbnails, fullscreen, RTL, keyboard navigation and customisations).",
"author": "yifaneye",
"license": "MIT",
Expand Down
16 changes: 16 additions & 0 deletions src/components/Carousel/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,20 @@ const GalleryCarousel = (props, ref) => {
isMaximized
);

/* check whether fallback image (if specified) returns an ok status */
const [fallbackImg, setFallbackImg] = useState(null);
useEffect(() => {
fetch(props.fallbackImg)
.then((res) => {
if (res.ok) {
setFallbackImg(props.fallbackImg);
}
})
.catch((_reason) => {
setFallbackImg(null);
});
});

const leftButton = widgetSettings.hasLeftButton && (
<LeftButton
position={widgetSettings.hasLeftButton}
Expand Down Expand Up @@ -483,6 +497,7 @@ const GalleryCarousel = (props, ref) => {
shouldLazyLoad={props.shouldLazyLoad}
curIndex={slides.curIndex}
callbacks={goToIndexCallbacksObject}
fallbackImg={fallbackImg}
/>
);

Expand Down Expand Up @@ -564,6 +579,7 @@ const GalleryCarousel = (props, ref) => {
widgetsHasShadow={props.widgetsHasShadow}
hasCaptions={settings.hasCaptions}
curIndex={slides.curIndex}
fallbackImg={fallbackImg}
/>
</div>
{widgets}
Expand Down
1 change: 1 addition & 0 deletions src/components/Carousel/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const propTypes = {
hasDotButtonsAtMax: largeWidgetPositions,
hasCaptionsAtMax: largeWidgetPositions,
hasThumbnailsAtMax: PropTypes.bool,
fallbackImg: PropTypes.string,
leftIcon: PropTypes.node,
rightIcon: PropTypes.node,
playIcon: PropTypes.node,
Expand Down
16 changes: 13 additions & 3 deletions src/components/Image/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ const LazyLoadedImage = (props) => {

let { src, srcset, alt, thumbnail, ...otherImageProps } = props.image;

src = isInViewport && !hasError ? src : PLACEHOLDER_IMAGE;
src =
isInViewport && !hasError ? src : props.fallbackImg ?? PLACEHOLDER_IMAGE;
srcset = isInViewport && !hasError ? srcset : null;
thumbnail = isInViewport && !hasError ? thumbnail : PLACEHOLDER_IMAGE;
thumbnail =
isInViewport && !hasError
? thumbnail
: props.fallbackImg ?? PLACEHOLDER_IMAGE;

return (
<>
Expand Down Expand Up @@ -81,11 +85,16 @@ export const Image = (props) => {

const { src, alt, srcset, thumbnail, ...otherImageProps } = props.image;

const handleError = (event) => {
event.target.src = props.fallbackImg ?? PLACEHOLDER_IMAGE;
};

const image = props.shouldLazyLoad ? (
<LazyLoadedImage
slidesContainerRef={props.slidesContainerRef}
image={props.image}
style={style}
fallbackImg={props.fallbackImg}
/>
) : (
<img
Expand Down Expand Up @@ -120,5 +129,6 @@ Image.propTypes = {
shouldLazyLoad: PropTypes.bool.isRequired,
slidesContainerRef: elementRef.isRequired,
hasCaption: largeWidgetPositions.isRequired,
widgetsHasShadow: PropTypes.bool.isRequired
widgetsHasShadow: PropTypes.bool.isRequired,
fallbackImg: PropTypes.string
};
15 changes: 9 additions & 6 deletions src/components/Image/ImageThumbnail.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import useIntersectionObserver from '../../utils/useIntersectionObserver';
import PropTypes from 'prop-types';
import { elementRef, imageObject } from '../../utils/validators';

const handleError = (event) => {
const handleError = (event, fallbackImg) => {
// permanently replace the image with the fallback image
event.target.src = PLACEHOLDER_IMAGE;
event.target.src = fallbackImg ?? PLACEHOLDER_IMAGE;
};

const LazyLoadedImageThumbnail = (props) => {
Expand All @@ -30,15 +30,16 @@ const LazyLoadedImageThumbnail = (props) => {
src={src}
alt={props.alt}
aria-label={props.alt}
onError={handleError}
onError={(event) => handleError(event, props.fallbackImg)}
/>
);
};

LazyLoadedImageThumbnail.propTypes = {
thumbnailsContainerRef: elementRef.isRequired,
src: PropTypes.string.isRequired,
alt: PropTypes.string
alt: PropTypes.string,
fallbackImg: PropTypes.string
};

export const ImageThumbnail = (props) => {
Expand All @@ -52,6 +53,7 @@ export const ImageThumbnail = (props) => {
thumbnailsContainerRef={props.thumbnailsContainerRef}
src={src}
alt={alt}
fallbackImg={props.fallbackImg}
/>
);

Expand All @@ -62,13 +64,14 @@ export const ImageThumbnail = (props) => {
alt={alt}
aria-label={alt}
loading='auto'
onError={handleError}
onError={(event) => handleError(event, props.fallbackImg)}
/>
);
};

ImageThumbnail.propTypes = {
image: imageObject.isRequired,
shouldLazyLoad: PropTypes.bool.isRequired,
thumbnailsContainerRef: elementRef.isRequired
thumbnailsContainerRef: elementRef.isRequired,
fallbackImg: PropTypes.string
};
4 changes: 3 additions & 1 deletion src/components/Slide/Slide.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const Slide = (props) => {
widgetsHasShadow={props.widgetsHasShadow}
hasCaption={props.hasCaption}
slidesContainerRef={props.slidesContainerRef}
fallbackImg={props.fallbackImg}
/>
) : (
<UserSlide slide={props.slide} />
Expand All @@ -44,5 +45,6 @@ Slide.propTypes = {
hasCaption: largeWidgetPositions.isRequired,
slidesContainerRef: elementRef.isRequired,
reference: elementRef,
isCurrent: PropTypes.bool.isRequired
isCurrent: PropTypes.bool.isRequired,
fallbackImg: PropTypes.string
};
4 changes: 3 additions & 1 deletion src/components/Slides/Slides.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const Slides = (props) => {
widgetsHasShadow={props.widgetsHasShadow}
hasCaption={props.hasCaptions}
isCurrent={index === props.curIndex}
fallbackImg={props.fallbackImg}
/>
);
})}
Expand All @@ -58,5 +59,6 @@ Slides.propTypes = {
objectFit: objectFitStyles.isRequired,
widgetsHasShadow: PropTypes.bool.isRequired,
hasCaptions: largeWidgetPositions.isRequired,
curIndex: PropTypes.number
curIndex: PropTypes.number,
fallbackImg: PropTypes.string
};
4 changes: 3 additions & 1 deletion src/components/Thumbnail/Thumbnail.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const Thumbnail = (props) => {
thumbnailsContainerRef={props.thumbnailsContainerRef}
image={props.slide}
shouldLazyLoad={props.shouldLazyLoad}
fallbackImg={props.fallbackImg}
/>
) : (
<UserSlideThumbnail slide={props.thumbnail} />
Expand Down Expand Up @@ -63,5 +64,6 @@ Thumbnail.propTypes = {
isCurrent: PropTypes.bool.isRequired,
width: PropTypes.string,
reference: elementRef.isRequired,
onClick: PropTypes.func.isRequired
onClick: PropTypes.func.isRequired,
fallbackImg: PropTypes.string
};
4 changes: 3 additions & 1 deletion src/components/Thumbnails/Thumbnails.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const Thumbnails = (props) => {
isCurrent={Number(key) === props.curIndex}
width={props.width}
onClick={callbacks[key]}
fallbackImg={props.fallbackImg}
/>
);
})}
Expand All @@ -61,7 +62,8 @@ Thumbnails.propTypes = {
thumbnails: PropTypes.array.isRequired,
hasImages: PropTypes.bool.isRequired,
shouldLazyLoad: PropTypes.bool.isRequired,
curIndex: PropTypes.number.isRequired
curIndex: PropTypes.number.isRequired,
fallbackImg: PropTypes.string
};

Thumbnails.defaultProps = {
Expand Down