diff --git a/frontend/src/components/TopNav.tsx b/frontend/src/components/TopNav.tsx index 57bf4a7..9762a3d 100644 --- a/frontend/src/components/TopNav.tsx +++ b/frontend/src/components/TopNav.tsx @@ -20,12 +20,13 @@ type Props = { user: User | null } export default (({ user }: Props) => { const location = useLocation () - const itemRefs = useRef<(HTMLAnchorElement | null)[]> ([]) + const dirRef = useRef<(-1) | 1> (1) + const itemsRef = useRef<(HTMLAnchorElement | null)[]> ([]) const navRef = useRef (null) const measure = () => { const nav = navRef.current - const el = itemRefs.current[activeIdx] + const el = itemsRef.current[activeIdx] if (!(nav) || !(el) || activeIdx < 0) return @@ -44,7 +45,6 @@ export default (({ user }: Props) => { const [menuOpen, setMenuOpen] = useState (false) const [openItemIdx, setOpenItemIdx] = useState (-1) const [postCount, setPostCount] = useState (null) - const [subDir, setSubDir] = useState<(-1) | 1> (1) const [wikiId, setWikiId] = useState (WikiIdBus.get ()) const wikiPageFlg = Boolean (/^\/wiki\/(?!new|changes)[^\/]+/.test (location.pathname) && wikiId) @@ -80,6 +80,14 @@ export default (({ user }: Props) => { const prevActiveIdxRef = useRef (activeIdx) + if (activeIdx !== prevActiveIdxRef.current) + { + dirRef.current = activeIdx > prevActiveIdxRef.current ? 1 : -1 + prevActiveIdxRef.current = activeIdx + } + + const dir = dirRef.current + useLayoutEffect (() => { if (activeIdx < 0) return @@ -99,15 +107,6 @@ export default (({ user }: Props) => { return () => unsubscribe () }, []) - useEffect (() => { - const prev = prevActiveIdxRef.current - if (prev !== activeIdx) - { - setSubDir (activeIdx > prev ? 1 : -1) - prevActiveIdxRef.current = activeIdx - } - }, [activeIdx]) - useEffect (() => { setMenuOpen (false) setOpenItemIdx (menu.findIndex (item => ( @@ -150,9 +149,9 @@ export default (({ user }: Props) => {
@@ -161,12 +160,10 @@ export default (({ user }: Props) => { { - itemRefs.current[i] = el + itemsRef.current[i] = el }} className={cn ('relative z-10 flex h-full items-center px-5', - ((i === openItemIdx) - ? 'font-bold' - : 'opacity-90 hover:opacity-100'))}> + (i === openItemIdx) && 'font-bold')}> {item.name} ))}
@@ -186,16 +183,20 @@ export default (({ user }: Props) => { -
- +
+ + custom={dir} + variants={{ enter: (d: -1 | 1) => ({ y: d * 24, opacity: 0 }), + centre: { y: 0, opacity: 1 }, + exit: (d: -1 | 1) => ({ y: (-d) * 24, opacity: 0 }) }} + className="absolute inset-0 flex items-center px-3" + initial="enter" + animate="centre" + exit="exit" + transition={{ duration: .2, ease: 'easeOut' }}> {(menu[activeIdx]?.subMenu ?? []) .filter (item => item.visible ?? true) .map ((item, i) => (