From 7c59da564ee8f5912ce44a7f0916fcaaea3c74bc Mon Sep 17 00:00:00 2001 From: Torkel Rogstad Date: Thu, 28 May 2026 20:50:34 +0200 Subject: [PATCH] fix: fade tray overlay backdrop on close --- .../web/src/overlays/overlay/OverlayContent.tsx | 10 +++------- packages/web/src/overlays/tray/Tray.tsx | 9 +++++++++ .../web/src/overlays/tray/__tests__/Tray.test.tsx | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/packages/web/src/overlays/overlay/OverlayContent.tsx b/packages/web/src/overlays/overlay/OverlayContent.tsx index 341aa45c16..d13e55b84c 100644 --- a/packages/web/src/overlays/overlay/OverlayContent.tsx +++ b/packages/web/src/overlays/overlay/OverlayContent.tsx @@ -29,16 +29,12 @@ export const OverlayContent = forwardRef( exit: 'exit', }); - const content = ( - - ); - return animated ? ( - - {content} + + ) : ( - content + ); }, ); diff --git a/packages/web/src/overlays/tray/Tray.tsx b/packages/web/src/overlays/tray/Tray.tsx index c8940a470d..6d387c452f 100644 --- a/packages/web/src/overlays/tray/Tray.tsx +++ b/packages/web/src/overlays/tray/Tray.tsx @@ -285,6 +285,7 @@ export const Tray = memo( const trayRef = useRef(null); const { observe: observeTraySize, height: trayHeight } = useDimensions(); const contentRef = useRef(null); + const overlayRef = useRef(null); const hasCalledOnOpenComplete = useRef(false); const [scope, animate] = useAnimate(); const dragControls = useDragControls(); @@ -317,6 +318,9 @@ export const Tray = memo( ? { x: pin === 'right' ? '100%' : '-100%' } : { y: pin === 'bottom' ? '100%' : '-100%' }; } + if (overlayRef.current) { + animate(overlayRef.current, { opacity: 0 }, animationConfig.slideOut.transition); + } animate(scope.current, finalAnimationValue, animationConfig.slideOut.transition).then(() => { setIsOpen(false); onClose?.(); @@ -326,6 +330,9 @@ export const Tray = memo( const handleSwipeClose = useCallback(() => { if (!scope.current) return; + if (overlayRef.current) { + animate(overlayRef.current, { opacity: 0 }, { duration: 0.15, ease: 'easeOut' }); + } animate(scope.current, { y: '100%' }, { duration: 0.15, ease: 'easeOut' }).then(() => { setIsOpen(false); onBlur?.(); @@ -451,6 +458,8 @@ export const Tray = memo( zIndex={zIndex} > { expect(root?.querySelector(`.${trayClassNames.handleBarHandle}`)).toBeInTheDocument(); }); }); + + describe('overlay animation', () => { + it('wraps the overlay in a motion container so the backdrop fades', () => { + const onCloseCompleteSpy = jest.fn(); + render( + + + {loremIpsum} + + , + ); + expect(screen.getByTestId('tray-overlay-motion')).toBeInTheDocument(); + }); + }); });