このコミットが含まれているのは:
2026-03-29 03:34:32 +09:00
コミット 09ff99309f
2個のファイルの変更73行の追加52行の削除
+59 -38
ファイルの表示
@@ -28,19 +28,23 @@ export default (({ user }: Props) => {
const measure = () => {
const nav = navRef.current
const el = itemsRef.current[activeIdx]
if (!(nav) || !(el) || activeIdx < 0)
return
const el = itemsRef.current[activeIdx < 0 ? menu.length : activeIdx]
if (!(nav) || !(el))
{
setHL ({ left: 0, width: 0, visible: true })
return
}
const navRect = nav.getBoundingClientRect ()
const elRect = el.getBoundingClientRect ()
setHl ({ left: elRect.left - navRect.left,
setHL ({ left: elRect.left - navRect.left,
width: elRect.width,
visible: true })
}
const [hl, setHl] = useState<{ left: number; width: number; visible: boolean }> ({
const [hl, setHL] = useState<{ left: number; width: number; visible: boolean }> ({
left: 0,
width: 0,
visible: false })
@@ -112,9 +116,6 @@ export default (({ user }: Props) => {
const dir = dirRef.current
useLayoutEffect (() => {
if (activeIdx < 0)
return
const raf = requestAnimationFrame (measure)
const onResize = () => requestAnimationFrame (measure)
@@ -171,6 +172,15 @@ export default (({ user }: Props) => {
(i === openItemIdx) && 'font-bold')}>
{item.name}
</PrefetchLink>))}
<PrefetchLink
to="#"
ref={(el: (HTMLAnchorElement | null)) => {
itemsRef.current[menu.length] = el
}}
className={cn ('relative z-10 flex h-full items-center px-5',
(openItemIdx < 0) && 'font-bold')}>
&raquo;
</PrefetchLink>
</div>
</div>
@@ -188,36 +198,47 @@ export default (({ user }: Props) => {
</a>
</nav>
<div className="relative hidden md:flex bg-yellow-200 dark:bg-red-950
items-center w-full min-h-[40px] overflow-hidden">
<AnimatePresence initial={false} custom={dir}>
<motion.div
key={activeIdx}
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) => (
'component' in item
? <Fragment key={`c-${ i }`}>{item.component}</Fragment>
: (
<PrefetchLink
key={`l-${ i }`}
to={item.to}
target={item.to.slice (0, 2) === '//' ? '_blank' : undefined}
className="h-full flex items-center px-3">
{item.name}
</PrefetchLink>)))}
</motion.div>
</AnimatePresence>
</div>
<AnimatePresence initial={false}>
{(menu[activeIdx]?.subMenu ?? []).length > 0 && (
<motion.div
key="submenu-shell"
className="relative hidden md:block overflow-hidden
bg-yellow-200 dark:bg-red-950"
initial={{ height: 0 }}
animate={{ height: 40 }}
exit={{ height: 0 }}
transition={{ duration: .2, ease: 'easeOut' }}>
<div className="relative h-[40px]">
<AnimatePresence initial={false} custom={dir}>
<motion.div
key={activeIdx}
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) => (
'component' in item
? <Fragment key={`c-${ i }`}>{item.component}</Fragment>
: (
<PrefetchLink
key={`l-${ i }`}
to={item.to}
target={item.to.slice (0, 2) === '//' ? '_blank' : undefined}
className="h-full flex items-center px-3">
{item.name}
</PrefetchLink>)))}
</motion.div>
</AnimatePresence>
</div>
</motion.div>)}
</AnimatePresence>
<AnimatePresence initial={false}>
{menuOpen && (