diff --git a/resources/js/guest/lib/__tests__/motion.test.ts b/resources/js/guest/lib/__tests__/motion.test.ts index d96c905..c61a1d5 100644 --- a/resources/js/guest/lib/__tests__/motion.test.ts +++ b/resources/js/guest/lib/__tests__/motion.test.ts @@ -1,4 +1,4 @@ -import { getMotionContainerPropsForNavigation, STAGGER_FAST } from '../motion'; +import { getMotionContainerPropsForNavigation, getMotionItemPropsForNavigation, STAGGER_FAST, FADE_UP } from '../motion'; describe('getMotionContainerPropsForNavigation', () => { it('returns initial hidden for POP navigation', () => { @@ -23,3 +23,25 @@ describe('getMotionContainerPropsForNavigation', () => { }); }); }); + +describe('getMotionItemPropsForNavigation', () => { + it('returns animate props for POP navigation', () => { + expect(getMotionItemPropsForNavigation(true, FADE_UP, 'POP')).toEqual({ + variants: FADE_UP, + initial: 'hidden', + animate: 'show', + }); + }); + + it('skips initial animation for PUSH navigation', () => { + expect(getMotionItemPropsForNavigation(true, FADE_UP, 'PUSH')).toEqual({ + variants: FADE_UP, + initial: false, + animate: 'show', + }); + }); + + it('returns empty props when motion disabled', () => { + expect(getMotionItemPropsForNavigation(false, FADE_UP, 'POP')).toEqual({}); + }); +}); diff --git a/resources/js/guest/lib/motion.ts b/resources/js/guest/lib/motion.ts index ae618da..aaa90e2 100644 --- a/resources/js/guest/lib/motion.ts +++ b/resources/js/guest/lib/motion.ts @@ -70,3 +70,17 @@ export function getMotionContainerPropsForNavigation( return { variants, initial, animate: 'show' } as const; } + +export function getMotionItemPropsForNavigation( + enabled: boolean, + variants: Variants, + navigationType: 'POP' | 'PUSH' | 'REPLACE' +) { + if (!enabled) { + return {}; + } + + const initial = navigationType === 'POP' ? 'hidden' : false; + + return { variants, initial, animate: 'show' } as const; +} diff --git a/resources/js/guest/pages/GalleryPage.tsx b/resources/js/guest/pages/GalleryPage.tsx index ad06f91..2cdb5f1 100644 --- a/resources/js/guest/pages/GalleryPage.tsx +++ b/resources/js/guest/pages/GalleryPage.tsx @@ -16,7 +16,14 @@ import { createPhotoShareLink } from '../services/photosApi'; import { cn } from '@/lib/utils'; import { useEventBranding } from '../context/EventBrandingContext'; import ShareSheet from '../components/ShareSheet'; -import { FADE_SCALE, FADE_UP, STAGGER_FAST, getMotionContainerPropsForNavigation, getMotionItemProps, prefersReducedMotion } from '../lib/motion'; +import { + FADE_SCALE, + FADE_UP, + STAGGER_FAST, + getMotionContainerPropsForNavigation, + getMotionItemPropsForNavigation, + prefersReducedMotion, +} from '../lib/motion'; import PullToRefresh from '../components/PullToRefresh'; import { triggerHaptic } from '../lib/haptics'; @@ -70,8 +77,8 @@ export default function GalleryPage() { const headingFont = branding.typography?.heading ?? branding.fontFamily ?? undefined; const motionEnabled = !prefersReducedMotion(); const containerMotion = getMotionContainerPropsForNavigation(motionEnabled, STAGGER_FAST, navigationType); - const fadeUpMotion = getMotionItemProps(motionEnabled, FADE_UP); - const fadeScaleMotion = getMotionItemProps(motionEnabled, FADE_SCALE); + const fadeUpMotion = getMotionItemPropsForNavigation(motionEnabled, FADE_UP, navigationType); + const fadeScaleMotion = getMotionItemPropsForNavigation(motionEnabled, FADE_SCALE, navigationType); const gridMotion = getMotionContainerPropsForNavigation(motionEnabled, STAGGER_FAST, navigationType); const [filter, setFilterState] = React.useState('latest'); const [currentPhotoIndex, setCurrentPhotoIndex] = React.useState(null); @@ -308,41 +315,51 @@ export default function GalleryPage() { releaseLabel={t('common.releaseToRefresh')} refreshingLabel={t('common.refreshing')} > - - -
- -
-
-

{t('galleryPage.title')}

-

{t('galleryPage.subtitle')}

-
+ + +
+
+
+ +
+
+

{t('galleryPage.title')}

+

{t('galleryPage.subtitle')}

+
+
- {newCount > 0 ? ( - - ) : ( - - {newPhotosBadgeText} - - )} + {newCount > 0 ? ( + + ) : ( + + {newPhotosBadgeText} + + )} +
- - + +
+ +
{loading && ( @@ -391,15 +408,24 @@ export default function GalleryPage() { }} loading="lazy" /> -
-
- {localizedTaskTitle &&

{localizedTaskTitle}

} -
- {createdLabel} - {p.uploader_name || t('galleryPage.photo.anonymous', 'Gast')} +
+
+ {localizedTaskTitle && ( +

+ {localizedTaskTitle} +

+ )} +
+ {createdLabel} + + {p.uploader_name || t('galleryPage.photo.anonymous', 'Gast')} +
-
+