Skip to content

Commit eb3c641

Browse files
feat: header 파일 추가
1 parent 340da68 commit eb3c641

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { style } from '@vanilla-extract/css';
2+
3+
import { colors } from '@/style/token/color.css';
4+
import { fonts } from '@/style/token/typography.css';
5+
6+
export const header = style({
7+
position: 'sticky',
8+
top: 0,
9+
zIndex: 100,
10+
width: '100%',
11+
backgroundColor: colors.bg_black01,
12+
display: 'flex',
13+
justifyContent: 'center',
14+
});
15+
16+
export const headerInner = style({
17+
width: '100%',
18+
maxWidth: '128rem',
19+
padding: '1.5rem 8rem',
20+
display: 'flex',
21+
justifyContent: 'space-between',
22+
alignItems: 'center',
23+
});
24+
25+
export const logo = style({
26+
color: colors.white01,
27+
...fonts.subtitle05,
28+
});
29+
30+
export const navWrapper = style({
31+
display: 'flex',
32+
gap: '2rem',
33+
});
34+
35+
export const navItem = style({
36+
display: 'flex',
37+
padding: '1.2rem 2rem',
38+
justifyContent: 'center',
39+
alignItems: 'center',
40+
flexShrink: 0,
41+
color: colors.grey6,
42+
textAlign: 'center',
43+
...fonts.subtitle05,
44+
background: 'transparent',
45+
border: 'none',
46+
cursor: 'pointer',
47+
whiteSpace: 'nowrap',
48+
transition: 'color 0.2s',
49+
selectors: {
50+
'&:hover': {
51+
color: colors.grey7,
52+
},
53+
},
54+
});
55+
56+
export const navItemActive = style({
57+
color: `${colors.grey11} !important`,
58+
selectors: {
59+
'&:hover': {
60+
color: `${colors.grey11} !important`,
61+
},
62+
},
63+
});
64+
65+
export const active = style({
66+
color: colors.grey11,
67+
});
68+
69+
export const profilePlaceholder = style({
70+
width: '5rem',
71+
height: '5rem',
72+
borderRadius: '50%',
73+
backgroundColor: colors.grey6,
74+
flexShrink: 0,
75+
});
76+
77+
export const loginButton = style({
78+
color: colors.grey11,
79+
textAlign: 'center',
80+
...fonts.subtitle05,
81+
background: 'transparent',
82+
border: 'none',
83+
cursor: 'pointer',
84+
transition: 'color 0.2s',
85+
selectors: {
86+
'&:hover': {
87+
color: colors.grey7,
88+
},
89+
},
90+
});
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { useState } from 'react';
2+
import { useNavigate } from 'react-router-dom';
3+
4+
import * as styles from './Header.css';
5+
6+
import { PATH } from '@/route/path';
7+
8+
const MENUS = [
9+
{ label: '나의 할 일', path: PATH.TODO },
10+
{ label: '나의 만다르트', path: PATH.MANDAL },
11+
{ label: '나의 히스토리', path: PATH.HISTORY },
12+
];
13+
14+
const Header = () => {
15+
const [activeMenu, setActiveMenu] = useState<string>(MENUS[0].label);
16+
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
17+
const navigate = useNavigate();
18+
19+
const handleLogin = () => {
20+
// 로그인 로직 추가하기
21+
setIsLoggedIn(true);
22+
};
23+
24+
const handleMenuClick = (menuLabel: string, path: string) => {
25+
setActiveMenu(menuLabel);
26+
navigate(path);
27+
};
28+
29+
return (
30+
<header className={styles.header}>
31+
<div className={styles.headerInner}>
32+
<h1 className={styles.logo}>NINEDOT</h1>
33+
34+
<nav className={styles.navWrapper}>
35+
{MENUS.map((menu) => (
36+
<button
37+
key={menu.label}
38+
className={`${styles.navItem} ${activeMenu === menu.label ? styles.navItemActive : ''}`}
39+
onClick={() => handleMenuClick(menu.label, menu.path)}
40+
aria-current={activeMenu === menu.label ? 'page' : undefined}
41+
>
42+
{menu.label}
43+
</button>
44+
))}
45+
</nav>
46+
47+
{isLoggedIn ? (
48+
<div className={styles.profilePlaceholder} />
49+
) : (
50+
<button className={styles.loginButton} onClick={handleLogin}>
51+
로그인
52+
</button>
53+
)}
54+
</div>
55+
</header>
56+
);
57+
};
58+
59+
export default Header;

0 commit comments

Comments
 (0)