アニメーション(#139) (#252)

#139

#139

#139

#139

#139

Merge branch 'feature/140' into feature/139

Merge remote-tracking branch 'origin/main' into feature/139

#140

Merge remote-tracking branch 'origin/main' into feature/140

Merge remote-tracking branch 'origin/main' into feature/140

#140 ぼちぼち

Merge remote-tracking branch 'origin/main' into feature/140

#140

#140

#140

#139 アニメーション

Co-authored-by: miteruzo <miteruzo@naver.com>
Reviewed-on: #252
This commit was merged in pull request #252.
This commit is contained in:
2026-02-05 23:25:27 +09:00
parent f3cd108b2e
commit 797e67ac37
22 changed files with 810 additions and 311 deletions
+48 -43
View File
@@ -1,18 +1,18 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import { AnimatePresence, motion } from 'framer-motion'
import { Fragment, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { useLocation } from 'react-router-dom'
import Separator from '@/components/MenuSeparator'
import PrefetchLink from '@/components/PrefetchLink'
import TopNavUser from '@/components/TopNavUser'
import { API_BASE_URL } from '@/config'
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
import { fetchTagByName } from '@/lib/tags'
import { cn } from '@/lib/utils'
import { fetchWikiPage } from '@/lib/wiki'
import type { FC } from 'react'
import type { FC, MouseEvent } from 'react'
import type { Menu, Tag, User, WikiPage } from '@/types'
import type { Menu, User } from '@/types'
type Props = { user: User | null }
@@ -120,11 +120,8 @@ export default (({ user }: Props) => {
const fetchPostCount = async () => {
try
{
const pageRes = await axios.get (`${ API_BASE_URL }/wiki/${ wikiId }`)
const wikiPage = toCamel (pageRes.data as any, { deep: true }) as WikiPage
const tagRes = await axios.get (`${ API_BASE_URL }/tags/name/${ wikiPage.title }`)
const tag = toCamel (tagRes.data as any, { deep: true }) as Tag
const wikiPage = await fetchWikiPage (String (wikiId ?? ''))
const tag = await fetchTagByName (wikiPage.title)
setPostCount (tag.postCount)
}
@@ -141,11 +138,15 @@ export default (({ user }: Props) => {
<nav className="px-3 flex justify-between items-center w-full min-h-[48px]
bg-yellow-200 dark:bg-red-975 md:bg-yellow-50">
<div className="flex items-center gap-2 h-full">
<Link to="/"
className="mx-4 text-xl font-bold text-pink-600 hover:text-pink-400
dark:text-pink-300 dark:hover:text-pink-100">
<PrefetchLink
to="/posts"
className="mx-4 text-xl font-bold text-pink-600 hover:text-pink-400
dark:text-pink-300 dark:hover:text-pink-100"
onClick={() => {
scroll (0, 0)
}}>
</Link>
</PrefetchLink>
<div ref={navRef} className="relative hidden md:flex h-full items-center">
<div aria-hidden
@@ -157,15 +158,16 @@ export default (({ user }: Props) => {
opacity: hl.visible ? 1 : 0 }}/>
{menu.map ((item, i) => (
<Link key={i}
to={item.to}
ref={el => {
itemsRef.current[i] = el
}}
className={cn ('relative z-10 flex h-full items-center px-5',
(i === openItemIdx) && 'font-bold')}>
<PrefetchLink
key={i}
to={item.to}
ref={(el: (HTMLAnchorElement | null)) => {
itemsRef.current[i] = el
}}
className={cn ('relative z-10 flex h-full items-center px-5',
(i === openItemIdx) && 'font-bold')}>
{item.name}
</Link>))}
</PrefetchLink>))}
</div>
</div>
@@ -203,11 +205,12 @@ export default (({ user }: Props) => {
'component' in item
? <Fragment key={`c-${ i }`}>{item.component}</Fragment>
: (
<Link key={`l-${ i }`}
to={item.to}
className="h-full flex items-center px-3">
<PrefetchLink
key={`l-${ i }`}
to={item.to}
className="h-full flex items-center px-3">
{item.name}
</Link>)))}
</PrefetchLink>)))}
</motion.div>
</AnimatePresence>
</div>
@@ -229,19 +232,20 @@ export default (({ user }: Props) => {
<Separator/>
{menu.map ((item, i) => (
<Fragment key={i}>
<Link to={i === openItemIdx ? item.to : '#'}
className={cn ('w-full min-h-[40px] flex items-center pl-8',
((i === openItemIdx)
&& 'font-bold bg-yellow-50 dark:bg-red-950'))}
onClick={ev => {
if (i !== openItemIdx)
{
ev.preventDefault ()
setOpenItemIdx (i)
}
}}>
<PrefetchLink
to={i === openItemIdx ? item.to : '#'}
className={cn ('w-full min-h-[40px] flex items-center pl-8',
((i === openItemIdx)
&& 'font-bold bg-yellow-50 dark:bg-red-950'))}
onClick={(ev: MouseEvent<HTMLAnchorElement>) => {
if (i !== openItemIdx)
{
ev.preventDefault ()
setOpenItemIdx (i)
}
}}>
{item.name}
</Link>
</PrefetchLink>
<AnimatePresence initial={false}>
{i === openItemIdx && (
@@ -267,11 +271,12 @@ export default (({ user }: Props) => {
{subItem.component}
</Fragment>)
: (
<Link key={`sp-l-${ i }-${ j }`}
to={subItem.to}
className="w-full min-h-[36px] flex items-center pl-12">
<PrefetchLink
key={`sp-l-${ i }-${ j }`}
to={subItem.to}
className="w-full min-h-[36px] flex items-center pl-12">
{subItem.name}
</Link>)))}
</PrefetchLink>)))}
</motion.div>)}
</AnimatePresence>
</Fragment>))}