Finesse navbar search animation
This commit is contained in:
parent
05b8a9c9f0
commit
a2745068e8
@ -33,11 +33,11 @@ const GAP_CLASS = 'mr-1.5 sm:mr-2';
|
||||
export default function AppViewSwitcher({
|
||||
currentSelection,
|
||||
className,
|
||||
animateSearch = true,
|
||||
animate = true,
|
||||
}: {
|
||||
currentSelection?: SwitcherSelection
|
||||
className?: string
|
||||
animateSearch?: boolean
|
||||
animate?: boolean
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
|
||||
@ -151,10 +151,10 @@ export default function AppViewSwitcher({
|
||||
</Switcher>
|
||||
{showSortControl &&
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.5 }}
|
||||
initial={animate ? { opacity: 0, scale: 0.5 } : false}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.5 }}
|
||||
transition={{ duration: 0.3, ease: 'easeInOut' }}
|
||||
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
||||
className={GAP_CLASS}
|
||||
>
|
||||
<Switcher className="max-sm:hidden">
|
||||
@ -172,7 +172,12 @@ export default function AppViewSwitcher({
|
||||
/>
|
||||
</Switcher>
|
||||
</motion.div>}
|
||||
<motion.div layout={animateSearch}>
|
||||
<motion.div
|
||||
// Conditional key necessary to halt/resume layout animations
|
||||
key={animate ? 'search' : 'search-no-animate'}
|
||||
layout={animate}
|
||||
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
||||
>
|
||||
<Switcher type="borderless">
|
||||
<SwitcherItem
|
||||
icon={<IconSearch includeTitle={false} />}
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
} from './config';
|
||||
import { useRef } from 'react';
|
||||
import useStickyNav from './useStickyNav';
|
||||
import { useAppState } from '@/state/AppState';
|
||||
|
||||
const NAV_HEIGHT_CLASS = NAV_CAPTION
|
||||
? 'min-h-[4rem] sm:min-h-[5rem]'
|
||||
@ -37,6 +38,10 @@ export default function Nav({
|
||||
const pathname = usePathname();
|
||||
const showNav = !isPathSignIn(pathname);
|
||||
|
||||
const {
|
||||
hasLoadedWithAnimations,
|
||||
} = useAppState();
|
||||
|
||||
const {
|
||||
classNameStickyContainer,
|
||||
classNameStickyNav,
|
||||
@ -86,7 +91,7 @@ export default function Nav({
|
||||
<AppViewSwitcher
|
||||
currentSelection={switcherSelectionForPath()}
|
||||
className="translate-x-[-1px]"
|
||||
animateSearch={isNavVisible}
|
||||
animate={hasLoadedWithAnimations && isNavVisible}
|
||||
/>
|
||||
<div className={clsx(
|
||||
'grow text-right min-w-0',
|
||||
|
||||
@ -19,7 +19,7 @@ export type AppStateContextType = {
|
||||
// CORE
|
||||
previousPathname?: string
|
||||
hasLoaded?: boolean
|
||||
setHasLoaded?: Dispatch<SetStateAction<boolean>>
|
||||
hasLoadedWithAnimations?: boolean
|
||||
swrTimestamp?: number
|
||||
invalidateSwr?: () => void
|
||||
nextPhotoAnimation?: AnimationConfig
|
||||
|
||||
@ -50,6 +50,8 @@ export default function AppStateProvider({
|
||||
// CORE
|
||||
const [hasLoaded, setHasLoaded] =
|
||||
useState(false);
|
||||
const [hasLoadedWithAnimations, setHasLoadedWithAnimations] =
|
||||
useState(false);
|
||||
const [swrTimestamp, setSwrTimestamp] =
|
||||
useState(Date.now());
|
||||
const [nextPhotoAnimation, _setNextPhotoAnimation] =
|
||||
@ -112,8 +114,13 @@ export default function AppStateProvider({
|
||||
useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setHasLoaded?.(true);
|
||||
setHasLoaded(true);
|
||||
storeTimezoneCookie();
|
||||
setUserEmailEager(getAuthEmailCookie());
|
||||
const timeout = setTimeout(() => {
|
||||
setHasLoadedWithAnimations(true);
|
||||
}, 1000);
|
||||
return () => clearTimeout(timeout);
|
||||
}, []);
|
||||
|
||||
const invalidateSwr = useCallback(() => setSwrTimestamp(Date.now()), []);
|
||||
@ -128,9 +135,6 @@ export default function AppStateProvider({
|
||||
error: authError,
|
||||
isLoading: isCheckingAuth,
|
||||
} = useSWR('getAuth', getAuthAction);
|
||||
useEffect(() => {
|
||||
setUserEmailEager(getAuthEmailCookie());
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (auth === null || authError) {
|
||||
setUserEmail(undefined);
|
||||
@ -207,7 +211,7 @@ export default function AppStateProvider({
|
||||
// CORE
|
||||
previousPathname,
|
||||
hasLoaded,
|
||||
setHasLoaded,
|
||||
hasLoadedWithAnimations,
|
||||
swrTimestamp,
|
||||
invalidateSwr,
|
||||
nextPhotoAnimation,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user