fix: dropdowns close on click-outside instead of hover-away
Build & Push Portfolio Image / build-push (push) Successful in 2m40s
Build & Push Portfolio Image / build-push (push) Successful in 2m40s
This commit is contained in:
+16
-4
@@ -3,7 +3,7 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { Menu, X } from 'lucide-react'
|
import { Menu, X } from 'lucide-react'
|
||||||
import { useState } from 'react'
|
import { useState, useEffect, useRef } from 'react'
|
||||||
import { useTerminal } from '@/lib/TerminalContext'
|
import { useTerminal } from '@/lib/TerminalContext'
|
||||||
import { useLanguage } from '@/lib/LanguageContext'
|
import { useLanguage } from '@/lib/LanguageContext'
|
||||||
import { CIStatusIndicator } from './CIStatusIndicator'
|
import { CIStatusIndicator } from './CIStatusIndicator'
|
||||||
@@ -28,7 +28,19 @@ export default function Header() {
|
|||||||
setLang(lang === 'en' ? 'zh' : 'en')
|
setLang(lang === 'en' ? 'zh' : 'en')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const skillsRef = useRef<HTMLDivElement>(null)
|
||||||
|
const contactRef = useRef<HTMLDivElement>(null)
|
||||||
|
const educationRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (e: MouseEvent) => {
|
||||||
|
if (skillsRef.current && !skillsRef.current.contains(e.target as Node)) setSkillsOpen(false)
|
||||||
|
if (contactRef.current && !contactRef.current.contains(e.target as Node)) setContactOpen(false)
|
||||||
|
if (educationRef.current && !educationRef.current.contains(e.target as Node)) setEducationOpen(false)
|
||||||
|
}
|
||||||
|
document.addEventListener('mousedown', handleClickOutside)
|
||||||
|
return () => document.removeEventListener('mousedown', handleClickOutside)
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 border-b border-gray-200 dark:border-gray-800 bg-white/95 dark:bg-gray-950/95 backdrop-blur">
|
<header className="sticky top-0 z-50 border-b border-gray-200 dark:border-gray-800 bg-white/95 dark:bg-gray-950/95 backdrop-blur">
|
||||||
@@ -55,7 +67,7 @@ export default function Header() {
|
|||||||
>
|
>
|
||||||
{t.header.nav.askPoimen}
|
{t.header.nav.askPoimen}
|
||||||
</button>
|
</button>
|
||||||
<div className="relative" onMouseLeave={() => setSkillsOpen(false)}>
|
<div className="relative" ref={skillsRef}>
|
||||||
<button
|
<button
|
||||||
onClick={() => setSkillsOpen(!skillsOpen)}
|
onClick={() => setSkillsOpen(!skillsOpen)}
|
||||||
className="text-sm hover:text-blue-600 dark:hover:text-blue-400"
|
className="text-sm hover:text-blue-600 dark:hover:text-blue-400"
|
||||||
@@ -83,7 +95,7 @@ export default function Header() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="relative" onMouseLeave={() => setContactOpen(false)}>
|
<div className="relative" ref={contactRef}>
|
||||||
<button
|
<button
|
||||||
onClick={() => setContactOpen(!contactOpen)}
|
onClick={() => setContactOpen(!contactOpen)}
|
||||||
className="text-sm hover:text-blue-600 dark:hover:text-blue-400"
|
className="text-sm hover:text-blue-600 dark:hover:text-blue-400"
|
||||||
@@ -173,7 +185,7 @@ export default function Header() {
|
|||||||
<div className="text-gray-600 dark:text-gray-400">{t.header.experience}</div>
|
<div className="text-gray-600 dark:text-gray-400">{t.header.experience}</div>
|
||||||
<div className="font-semibold text-gray-900 dark:text-white">{t.header.experienceValue}</div>
|
<div className="font-semibold text-gray-900 dark:text-white">{t.header.experienceValue}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative" onMouseLeave={() => setEducationOpen(false)}>
|
<div className="relative" ref={educationRef}>
|
||||||
<button
|
<button
|
||||||
onClick={() => setEducationOpen(!educationOpen)}
|
onClick={() => setEducationOpen(!educationOpen)}
|
||||||
className="text-xs cursor-pointer hover:text-blue-600 dark:hover:text-blue-400"
|
className="text-xs cursor-pointer hover:text-blue-600 dark:hover:text-blue-400"
|
||||||
|
|||||||
Reference in New Issue
Block a user