Skip to content

Commit 0916014

Browse files
committed
fix(image-lightbox): fix closing animation cut short because of unstable image reference
1 parent 2f0da61 commit 0916014

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12-
- `Slideshow`: Changed active pagination item width for better a11y.
12+
- `Slideshow`: changed active pagination item width for better a11y.
13+
- `ImageLightbox`: fix closing animation cut short because of unstable image reference.
1314

1415
## [3.9.1][] - 2024-09-17
1516

packages/lumx-react/src/components/image-lightbox/useImageLightbox.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,12 @@ export function useImageLightbox<P extends Partial<ImageLightboxProps>>(
4141
const propsRef = React.useRef(props);
4242

4343
React.useEffect(() => {
44-
const newProps = { ...props };
45-
if (newProps?.images) {
46-
newProps.images = newProps.images.map((image) => ({ imgRef: React.createRef(), ...image }));
47-
}
48-
propsRef.current = newProps;
44+
propsRef.current = props;
4945
}, [props]);
5046

47+
// Keep reference for each image elements
48+
const imageRefsRef = React.useRef<Array<React.RefObject<HTMLImageElement>>>([]);
49+
5150
const currentImageRef = React.useRef<HTMLImageElement>(null);
5251
const [imageLightboxProps, setImageLightboxProps] = React.useState(
5352
() => ({ ...EMPTY_PROPS, ...props }) as ManagedProps & P,
@@ -61,8 +60,8 @@ export function useImageLightbox<P extends Partial<ImageLightboxProps>>(
6160
if (!currentImage) {
6261
return;
6362
}
64-
const currentIndex = propsRef.current?.images?.findIndex(
65-
({ imgRef }) => (imgRef as any)?.current === currentImage,
63+
const currentIndex = imageRefsRef.current.findIndex(
64+
(imageRef) => imageRef.current === currentImage,
6665
) as number;
6766

6867
await startViewTransition({
@@ -83,12 +82,20 @@ export function useImageLightbox<P extends Partial<ImageLightboxProps>>(
8382
// If we find an image inside the trigger, animate it in transition with the opening image
8483
const triggerImage = triggerImageRefs[activeImageIndex as any]?.current || findImage(triggerElement);
8584

86-
// Inject the trigger image as loading placeholder for better loading state
87-
const imagesWithFallbackSize = propsRef.current?.images?.map((image, idx) => {
88-
if (triggerImage && idx === activeImageIndex && !image.loadingPlaceholderImageRef) {
89-
return { ...image, loadingPlaceholderImageRef: { current: triggerImage } };
85+
// Inject refs to improve transition and loading style
86+
const images = propsRef.current?.images?.map((image, idx) => {
87+
// Get or create image reference
88+
let imgRef = imageRefsRef.current[idx];
89+
if (!imgRef) {
90+
imgRef = React.createRef();
91+
imageRefsRef.current[idx] = imgRef;
9092
}
91-
return image;
93+
94+
// Try to use the trigger image as the loading placeholder
95+
const loadingPlaceholderImageRef =
96+
triggerImage && idx === activeImageIndex ? { current: triggerImage } : undefined;
97+
98+
return { loadingPlaceholderImageRef, ...image, imgRef };
9299
});
93100

94101
await startViewTransition({
@@ -104,7 +111,7 @@ export function useImageLightbox<P extends Partial<ImageLightboxProps>>(
104111
close();
105112
prevProps?.onClose?.();
106113
},
107-
images: imagesWithFallbackSize,
114+
images,
108115
activeImageIndex: activeImageIndex || 0,
109116
}));
110117
},

0 commit comments

Comments
 (0)