diff --git a/packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/EmblaImageGalleryPrototype.jsx b/packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/EmblaImageGalleryPrototype.jsx new file mode 100644 index 0000000000..110319ec5f --- /dev/null +++ b/packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/EmblaImageGalleryPrototype.jsx @@ -0,0 +1,134 @@ +//@ts-check +import React, { useState, useEffect, useCallback } from "react"; +import useEmblaCarousel from "embla-carousel-react"; +import PropTypes from "prop-types"; + +const EmblaImageGalleryPrototype = ({ + imageItems = [], + hasContent = false, + maxWidth = "996px" +}) => { + //Initializing Embla + const [emblaRef, emblaApi] = useEmblaCarousel({ loop: false, align: "start" }); + + //React state to track the active slide + const [selectedIndex, setSelectedIndex] = useState(0); + + //Navigation controls + const scrollPrev = useCallback(() => emblaApi && emblaApi.scrollPrev(), [emblaApi]); + const scrollNext = useCallback(() => emblaApi && emblaApi.scrollNext(), [emblaApi]); + const scrollTo = useCallback((index) => emblaApi && emblaApi.scrollTo(index), [emblaApi]); + + const onSelect = useCallback(() => { + if (!emblaApi) return; + setSelectedIndex(emblaApi.selectedScrollSnap()); //save number to react state + }, [emblaApi]); + + //Use direct react callback to update uI + useEffect(() => { + if (!emblaApi) return; + emblaApi.on("select", onSelect); + emblaApi.on("reInit", onSelect); + onSelect(); //Set initial state on load + }, [emblaApi, onSelect]); + + if (!imageItems || imageItems.length === 0) return null; //prevent website from crashing if empty data + + const currentItem = imageItems[selectedIndex]; + + return ( + //600px so it matches storybook wrapper limit (temperory) +
+ +
{/* force images to shrink and fit */} + +
+ {imageItems.map((item) => ( //iterate and render every image inside contatiner +
+ {item.imageAltText +
+ ))} +
+
+ + {/* prevent nav bar from getting reduced in size */} +
+ + {/* Arrows */} +
+ + + + {/* thumbnails in nav bar */} +
{/* allow scrolling images if too many */} + {/* clickable thumbnail images */} + {imageItems.map((item, index) => ( + + ))} +
+ + +
+ + {/* Captions */} + {hasContent && (currentItem.title || currentItem.content) && ( //hide if no text caption +
+
+ {currentItem.title &&

{currentItem.title}

} +
+
+
+ )} +
+
+ ); +}; + +EmblaImageGalleryPrototype.propTypes = { + imageItems: PropTypes.array.isRequired, + hasContent: PropTypes.bool, + maxWidth: PropTypes.string, +}; + +export { EmblaImageGalleryPrototype }; + diff --git a/packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/ImageGalleryCarousel.stories.jsx b/packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/ImageGalleryCarousel.stories.jsx index b6122c462e..113df4ea12 100644 --- a/packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/ImageGalleryCarousel.stories.jsx +++ b/packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/ImageGalleryCarousel.stories.jsx @@ -121,3 +121,15 @@ export const ImageCarouselWithMoreContent = () => ( /> ); + +import { EmblaImageGalleryPrototype } from "./EmblaImageGalleryPrototype"; + +export const EmblaPrototype = () => ( + + + +);