2
2
3
3
import { useState , useEffect } from 'react'
4
4
import { motion , AnimatePresence } from 'framer-motion'
5
+ import clsx from 'clsx'
5
6
6
- import AboutMe from '@/assets/aboutMe.svg'
7
- import Blog from '@/assets/blog.svg'
8
- // import Portfolio from '@/assets/portfolio.svg'
9
7
import DarkModeToggle from './sub/DarkModeToggle'
10
8
import { usePreventScroll } from '@/hooks/usePreventScroll'
11
- import Button from './sub/Button'
9
+ import { useSmoothScroll } from '@/hooks/useSmoothScroll'
10
+ import { navbarData } from '@/assets/index'
12
11
13
- interface NavItem {
14
- icon : any ;
15
- text : string ;
16
- href : string ;
17
- }
12
+ import Button from './sub/Button'
18
13
19
14
export default function Header ( ) {
20
15
const [ isOpen , setIsOpen ] = useState ( false ) ;
21
16
const [ isMobile , setIsMobile ] = useState ( true ) ;
22
-
23
- const navItems : NavItem [ ] = [
24
- { icon : AboutMe , text : 'About Me' , href : '/' } ,
25
- { icon : Blog , text : 'Blog' , href : 'https://daunje0.tistory.com/' } ,
26
- // { icon: Portfolio, text: 'Portfolio', href: '/' },
27
- ] ;
17
+ const { scrollToElement } = useSmoothScroll ( ) ;
28
18
29
19
useEffect ( ( ) => {
30
20
const handleResize = ( ) => {
@@ -41,11 +31,17 @@ export default function Header() {
41
31
setIsOpen ( ! isOpen ) ;
42
32
} ;
43
33
34
+ // 스크롤 이동과 메뉴 닫기를 함께 처리하는 핸들러
35
+ const handleScrollAndClose = ( e : React . MouseEvent < HTMLAnchorElement > , id : string ) => {
36
+ setIsOpen ( false ) ;
37
+ scrollToElement ( e , id ) ;
38
+ } ;
39
+
44
40
usePreventScroll ( isOpen && isMobile ) ;
45
41
46
42
return (
47
- < header className = "relative z-50" >
48
- < div className = "flex justify-between items-center" >
43
+ < header className = "fixed top-0 left-0 w-full pt-8 bg-white/80 dark:bg-black/80 backdrop-blur-sm z-50 px-4 py-2 " >
44
+ < div className = "flex justify-between items-center max-w-7xl mx-auto " >
49
45
< nav className = 'relative flex-grow' >
50
46
< AnimatePresence >
51
47
{ ( isOpen || ! isMobile ) && (
@@ -65,23 +61,28 @@ export default function Header() {
65
61
bg-slate-100/95 dark:bg-black/95 dark:sm:bg-transparent sm:bg-transparent
66
62
flex flex-col items-center justify-center gap-10 z-50
67
63
` }
68
-
69
64
>
70
- { navItems . map ( ( { icon : Icon , text , href } ) => (
65
+ { navbarData . map ( ( item , i ) => (
71
66
< motion . div
72
- key = { text }
67
+ key = { item . id }
73
68
whileHover = { { scale : 1.2 } }
74
69
whileTap = { { scale : 0.9 } }
75
70
transition = { { type : "spring" , stiffness : 400 , damping : 17 } }
76
71
>
77
- < Icon className = 'size-6' />
78
- < li >
79
- { /* <Link href={href}>{text}</Link> */ }
80
- < a href = { href }
81
- target = "_blank"
82
- rel = "noopener noreferrer"
83
- > { text } </ a >
84
- </ li >
72
+ < a
73
+ href = { `/#${ item . id } ` }
74
+ onClick = { ( e ) => handleScrollAndClose ( e , item . id ) }
75
+ className = "flex flex-row items-center gap-x-2"
76
+ >
77
+ < i className = { `${ item . icon } text-3xl text-yellow-600 leading-none` } > </ i >
78
+ < span className = { clsx (
79
+ 'text-xl tracking-wide text-center dark:text-white leading-none' ,
80
+ 'transition-all duration-300' ,
81
+ 'sm:opacity-0 sm:group-hover:opacity-100 md:opacity-100'
82
+ ) } >
83
+ { item . name }
84
+ </ span >
85
+ </ a >
85
86
</ motion . div >
86
87
) ) }
87
88
</ motion . ul >
@@ -115,6 +116,6 @@ export default function Header() {
115
116
< DarkModeToggle />
116
117
</ div >
117
118
</ div >
118
- </ header >
119
+ </ header >
119
120
)
120
121
}
0 commit comments