|
|
@@ -28,19 +28,23 @@ export default (({ user }: Props) => { |
|
|
|
|
|
|
|
|
const measure = () => { |
|
|
const measure = () => { |
|
|
const nav = navRef.current |
|
|
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 navRect = nav.getBoundingClientRect () |
|
|
const elRect = el.getBoundingClientRect () |
|
|
const elRect = el.getBoundingClientRect () |
|
|
|
|
|
|
|
|
setHl ({ left: elRect.left - navRect.left, |
|
|
|
|
|
|
|
|
setHL ({ left: elRect.left - navRect.left, |
|
|
width: elRect.width, |
|
|
width: elRect.width, |
|
|
visible: true }) |
|
|
visible: true }) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const [hl, setHl] = useState<{ left: number; width: number; visible: boolean }> ({ |
|
|
|
|
|
|
|
|
const [hl, setHL] = useState<{ left: number; width: number; visible: boolean }> ({ |
|
|
left: 0, |
|
|
left: 0, |
|
|
width: 0, |
|
|
width: 0, |
|
|
visible: false }) |
|
|
visible: false }) |
|
|
@@ -112,9 +116,6 @@ export default (({ user }: Props) => { |
|
|
const dir = dirRef.current |
|
|
const dir = dirRef.current |
|
|
|
|
|
|
|
|
useLayoutEffect (() => { |
|
|
useLayoutEffect (() => { |
|
|
if (activeIdx < 0) |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
const raf = requestAnimationFrame (measure) |
|
|
const raf = requestAnimationFrame (measure) |
|
|
const onResize = () => requestAnimationFrame (measure) |
|
|
const onResize = () => requestAnimationFrame (measure) |
|
|
|
|
|
|
|
|
@@ -171,6 +172,15 @@ export default (({ user }: Props) => { |
|
|
(i === openItemIdx) && 'font-bold')}> |
|
|
(i === openItemIdx) && 'font-bold')}> |
|
|
{item.name} |
|
|
{item.name} |
|
|
</PrefetchLink>))} |
|
|
</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')}> |
|
|
|
|
|
その他 » |
|
|
|
|
|
</PrefetchLink> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
@@ -188,36 +198,47 @@ export default (({ user }: Props) => { |
|
|
</a> |
|
|
</a> |
|
|
</nav> |
|
|
</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}> |
|
|
<AnimatePresence initial={false}> |
|
|
{menuOpen && ( |
|
|
{menuOpen && ( |
|
|
|