feat: use hover to open dropdown-menu

This commit is contained in:
Ou 2024-10-21 15:23:51 +08:00
parent 0e2d5bc25b
commit d285f37eeb

View File

@ -1,8 +1,8 @@
import { Homepage } from "@shared/consts" import { Homepage } from "@shared/consts"
import clsx from "clsx" import clsx from "clsx"
import { motion } from "framer-motion" import { motion } from "framer-motion"
import { useRef, useState } from "react" import { useEffect, useRef, useState } from "react"
import { useClickAway } from "react-use" import { useHoverDirty } from "react-use"
import { useDark } from "~/hooks/useDark" import { useDark } from "~/hooks/useDark"
import { useLogin } from "~/hooks/useLogin" import { useLogin } from "~/hooks/useLogin"
@ -21,13 +21,14 @@ function ThemeToggle() {
export function Menu() { export function Menu() {
const { loggedIn, login, logout, enabledLogin, userInfo } = useLogin() const { loggedIn, login, logout, enabledLogin, userInfo } = useLogin()
const [shown, show] = useState(false) const [shown, show] = useState(false)
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLElement>(null)
useClickAway(ref, () => { const isHover = useHoverDirty(ref)
show(false) useEffect(() => {
}) show(isHover)
}, [shown, isHover])
return ( return (
<span ref={ref} className="relative"> <span ref={ref} className="relative">
<span className="flex items-center scale-90" onClick={() => show(!shown)}> <span className="flex items-center scale-90">
{ {
enabledLogin && loggedIn && userInfo.avatar enabledLogin && loggedIn && userInfo.avatar
? ( ? (
@ -46,39 +47,41 @@ export function Menu() {
} }
</span> </span>
{shown && ( {shown && (
<motion.div <div className="absolute right-0 z-99 bg-transparent pt-8 top-0">
id="dropdown-menu" <motion.div
className={clsx([ id="dropdown-menu"
"absolute top-2rem right-0 z-99 w-200px", className={clsx([
"bg-primary p-1px backdrop-blur-5 bg-op-70! rounded-lg", "w-200px",
])} "bg-primary p-1px backdrop-blur-5 bg-op-70! rounded-lg",
initial={{ ])}
scale: 0.9, initial={{
}} scale: 0.9,
animate={{ }}
scale: 1, animate={{
}} scale: 1,
> }}
<ol className="bg-base bg-op-70! backdrop-blur-md p-2 rounded-lg color-base text-base"> >
{enabledLogin && !loggedIn && ( <ol className="bg-base bg-op-70! backdrop-blur-md p-2 rounded-lg color-base text-base">
<li onClick={login}> {enabledLogin && !loggedIn && (
<span className="i-ph:sign-in-duotone inline-block" /> <li onClick={login}>
<span>Github </span> <span className="i-ph:sign-in-duotone inline-block" />
<span>Github </span>
</li>
)}
{enabledLogin && loggedIn && (
<li onClick={logout}>
<span className="i-ph:sign-out-duotone inline-block" />
<span>退</span>
</li>
)}
<ThemeToggle />
<li onClick={() => window.open(Homepage)}>
<span className="i-ph:github-logo-duotone inline-block" />
<span>Star on Github </span>
</li> </li>
)} </ol>
{enabledLogin && loggedIn && ( </motion.div>
<li onClick={logout}> </div>
<span className="i-ph:sign-out-duotone inline-block" />
<span>退</span>
</li>
)}
<ThemeToggle />
<li onClick={() => window.open(Homepage)}>
<span className="i-ph:github-logo-duotone inline-block" />
<span>Star on Github </span>
</li>
</ol>
</motion.div>
)} )}
</span> </span>
) )