From 64290817ee784f22e77a961e4c3ca5d877dee827 Mon Sep 17 00:00:00 2001 From: Ojas Atkar Date: Wed, 19 Aug 2026 13:54:30 -0700 Subject: [PATCH 1/4] feat(unity-react-core): embla carousel prototype for image gallery --- .../EmblaImageGalleryPrototype.jsx | 134 ++++++++++++++++++ .../ImageGalleryCarousel.stories.jsx | 12 ++ 2 files changed, 146 insertions(+) create mode 100644 packages/unity-react-core/src/components/ComponentCarousel/components/ImageGalleryCarousel/EmblaImageGalleryPrototype.jsx 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 = () => ( + + + +); From 69015c66b6663b9051485c9ec115796075f1f89d Mon Sep 17 00:00:00 2001 From: Ojas Atkar Date: Fri, 28 Aug 2026 11:13:27 -0700 Subject: [PATCH 2/4] fix(unity-react-core): embla carousel code --- package.json | 3 +++ packages/unity-react-core/package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/package.json b/package.json index 58450d3bde..bb2339fd11 100644 --- a/package.json +++ b/package.json @@ -122,5 +122,8 @@ "commitizen": { "path": "./scripts/conventional-commits.js" } + }, + "dependencies": { + "embla-carousel-react": "^8.6.0" } } diff --git a/packages/unity-react-core/package.json b/packages/unity-react-core/package.json index c0364c0cd1..1ec177afbd 100644 --- a/packages/unity-react-core/package.json +++ b/packages/unity-react-core/package.json @@ -104,6 +104,7 @@ }, "dependencies": { "@glidejs/glide": "^3.6.0", + "embla-carousel-react": "^8.6.0", "react-share": "^5.3" }, "peerDependencies": { From 101184fdb755f6b221156c5b828450a1a6459001 Mon Sep 17 00:00:00 2001 From: Ojas Atkar Date: Fri, 28 Aug 2026 11:21:17 -0700 Subject: [PATCH 3/4] fix(unity-react-core): removinf embla from root --- package.json | 3 --- yarn.lock | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index bb2339fd11..58450d3bde 100644 --- a/package.json +++ b/package.json @@ -122,8 +122,5 @@ "commitizen": { "path": "./scripts/conventional-commits.js" } - }, - "dependencies": { - "embla-carousel-react": "^8.6.0" } } diff --git a/yarn.lock b/yarn.lock index a270a21578..48e21658c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -517,6 +517,7 @@ __metadata: chromium-bidi: "npm:^3.0.0" classnames: "npm:^2.2.6" css-loader: "npm:^5.2.0" + embla-carousel-react: "npm:^8.6.0" file-loader: "npm:^6.2.0" glob: "npm:^7.1.6" html-entities: "npm:^2.3.1" @@ -10741,6 +10742,7 @@ __metadata: cz-conventional-changelog: "npm:^3.3.0" diff: "npm:^8.0.2" dompurify: "npm:^3.4.10" + embla-carousel-react: "npm:^8.6.0" eslint: "npm:^9" eslint-config-prettier: "npm:^8.2.0" eslint-plugin-import: "npm:^2.22.1" @@ -14359,6 +14361,34 @@ __metadata: languageName: node linkType: hard +"embla-carousel-react@npm:^8.6.0": + version: 8.6.0 + resolution: "embla-carousel-react@npm:8.6.0" + dependencies: + embla-carousel: "npm:8.6.0" + embla-carousel-reactive-utils: "npm:8.6.0" + peerDependencies: + react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + checksum: 10c0/461b0c427a6fca62e730c7b39d08e9c55b01a2138c173d5b9ebf77ec92092a900b45ac384731c77382b48d5d65946994d3abba6e9899a66d6e16f8ddf191ed1c + languageName: node + linkType: hard + +"embla-carousel-reactive-utils@npm:8.6.0": + version: 8.6.0 + resolution: "embla-carousel-reactive-utils@npm:8.6.0" + peerDependencies: + embla-carousel: 8.6.0 + checksum: 10c0/33d07e6df4d8dec9b4fc95858838ea2d5e5df078039c05b2a342c05ba4979d8d18564a1c607da445fed744daf969a0b5a90124ce487a854e86ced6f0458b51e9 + languageName: node + linkType: hard + +"embla-carousel@npm:8.6.0": + version: 8.6.0 + resolution: "embla-carousel@npm:8.6.0" + checksum: 10c0/f4c598e7be28b70340d31ffd2bebb2472db370b0c81d9b089bf9555cf618695f35dc4a0694565c994c9ab972731123063f945aa09ff485df0df761d79c6a08ef + languageName: node + linkType: hard + "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" From 73f5f885490a57d2983f04c47fbe8dbd52a9aca7 Mon Sep 17 00:00:00 2001 From: Ojas Atkar Date: Fri, 28 Aug 2026 11:23:34 -0700 Subject: [PATCH 4/4] fix(unity-react-core): embla --- yarn.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 48e21658c5..35100528e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10742,7 +10742,6 @@ __metadata: cz-conventional-changelog: "npm:^3.3.0" diff: "npm:^8.0.2" dompurify: "npm:^3.4.10" - embla-carousel-react: "npm:^8.6.0" eslint: "npm:^9" eslint-config-prettier: "npm:^8.2.0" eslint-plugin-import: "npm:^2.22.1"