-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Design] Mobile ver. - Header 반응형 구현 (#371)
* init: 파일 생성 * fix: theme color 네이밍 범용적으로 수정 * move: Nav 디렉토리 만들어서 컴포넌트 분리 * feat: react-responsive 설치 및 useDevice hook 추가 * feat: isTablet, isMobile 공용 useDevice 추가 * fix: Logo svg className prop 확장 * chore: PC지원 막기 임시 해제 * design: tab/mob ver. 헤더 로고, 햄버거 조건부 렌더링 * design: 햄버거 토클 시 background 변경 * fix: TextBox이메일 width 처리 누락 해결 * fix: 달라진 useDevice 반환값에 따른 수정 * fix: header position fixed로 수정 및 layout marginTop 추가 * design: header padding 반응형 * fix: 디자인 변경사항 (padding값) 반영 * feat: Nav 내부의 MenuList 컴포넌트 분리 * design: 드롬메뉴 헤더 반응형 * feat: DEVICE_TYPE에 따라 isMenuOpen값 초기화 * feat: 햄버거 버튼과 닫기 버튼 * design: dimmed 배경 * feat: dimmed 배경 클릭 시 헤더 닫히도록 * design: 반응형 header 드롭메뉴 애니메이션 * design: 반응형 header active 페이지 bolder 추가 * design: 햄버거버튼 다크모드 조건부스타일링 * feat: 애니메이션 keyframes 공통 animationa.css.ts로 분리
- Loading branch information
Showing
19 changed files
with
433 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 0 additions & 24 deletions
24
src/common/components/Layout/components/Header/MenuItem/style.css.ts
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
src/common/components/Layout/components/Header/Nav/MenuItem/style.css.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { style, styleVariants } from '@vanilla-extract/css'; | ||
|
||
import { theme } from 'styles/theme.css'; | ||
|
||
const menuItem = style({ | ||
...theme.font.HEADING_6_18_B, | ||
}); | ||
|
||
export const menuItemVar = styleVariants({ | ||
DESK: [ | ||
menuItem, | ||
{ | ||
color: theme.color.baseText, | ||
}, | ||
], | ||
TAB: [ | ||
menuItem, | ||
{ | ||
color: theme.color.grayButtonFill, | ||
}, | ||
], | ||
MOB: [ | ||
menuItem, | ||
{ | ||
color: theme.color.grayButtonFill, | ||
}, | ||
], | ||
}); | ||
|
||
const menuLink = style({ | ||
textDecoration: `underline transparent 2px`, | ||
textUnderlineOffset: 21, | ||
transition: 'all 0.2s ease-out', | ||
cursor: 'pointer', | ||
}); | ||
|
||
export const menuLinkVar = styleVariants( | ||
{ | ||
DESK: { | ||
hover: { | ||
textDecorationColor: theme.color.primary, | ||
}, | ||
active: { | ||
color: theme.color.primary, | ||
}, | ||
}, | ||
TAB: { | ||
hover: { | ||
color: theme.color.whiteButtonFill, | ||
}, | ||
active: { | ||
color: theme.color.whiteButtonFill, | ||
fontWeight: 'bolder', | ||
}, | ||
}, | ||
MOB: { | ||
hover: { | ||
color: theme.color.whiteButtonFill, | ||
}, | ||
active: { | ||
color: theme.color.whiteButtonFill, | ||
fontWeight: 'bolder', | ||
}, | ||
}, | ||
}, | ||
({ hover, active }) => [ | ||
menuLink, | ||
{ | ||
selectors: { | ||
'&:hover:not([disabled])': hover, | ||
'&.active': active, | ||
}, | ||
}, | ||
], | ||
); |
73 changes: 73 additions & 0 deletions
73
src/common/components/Layout/components/Header/Nav/MenuList/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { reset, track } from '@amplitude/analytics-browser'; | ||
import { useContext, useEffect, useState } from 'react'; | ||
import { useLocation, useNavigate } from 'react-router-dom'; | ||
|
||
import { useDevice } from '@hooks/useDevice'; | ||
import { RecruitingInfoContext } from '@store/recruitingInfoContext'; | ||
|
||
import { dimmedBgVar, menuContainerVar, menuList, menuMobListVar } from './style.css'; | ||
import { MENU_ITEMS, MENU_ITEMS_MAKERS } from '../../contants'; | ||
import MenuItem from '../MenuItem'; | ||
|
||
const MenuList = ({ isMenuOpen, onClickMenuToggle }: { isMenuOpen?: boolean; onClickMenuToggle?: () => void }) => { | ||
const DEVICE_TYPE = useDevice(); | ||
const navigate = useNavigate(); | ||
const { pathname } = useLocation(); | ||
const [isShown, setIsShown] = useState(isMenuOpen); | ||
const [animation, setAnimation] = useState<'open' | 'close'>(isMenuOpen ? 'open' : 'close'); | ||
|
||
useEffect(() => { | ||
if (isMenuOpen) { | ||
setIsShown(true); | ||
setAnimation('open'); | ||
} else { | ||
setAnimation('close'); | ||
const timer = setTimeout(() => setIsShown(false), 300); | ||
return () => clearTimeout(timer); | ||
} | ||
}, [isMenuOpen]); | ||
|
||
const isSignedIn = localStorage.getItem('soptApplyAccessToken'); | ||
|
||
const { | ||
recruitingInfo: { name, isMakers }, | ||
} = useContext(RecruitingInfoContext); | ||
const menuItems = isMakers ? MENU_ITEMS_MAKERS : MENU_ITEMS; | ||
const handleLogout = () => { | ||
track('click-gnb-logout'); | ||
reset(); | ||
localStorage.removeItem('soptApplyAccessToken'); | ||
localStorage.removeItem('soptApplyAccessTokenExpiredTime'); | ||
pathname === '/' ? window.location.reload() : navigate('/'); | ||
}; | ||
|
||
if (onClickMenuToggle && !isShown) return null; | ||
|
||
return ( | ||
<nav> | ||
<ul | ||
className={DEVICE_TYPE !== 'DESK' ? `${menuMobListVar[DEVICE_TYPE]} ${menuContainerVar[animation]}` : menuList}> | ||
{!isSignedIn && ( | ||
<> | ||
{menuItems.map(({ text, path, target, amplitudeId }) => ( | ||
<MenuItem key={text} text={text} path={path} target={target} amplitudeId={amplitudeId} /> | ||
))} | ||
<MenuItem key="로그인" text="로그인" path="/" amplitudeId="click-gnb-signin" /> | ||
</> | ||
)} | ||
{isSignedIn && name && ( | ||
<> | ||
{menuItems.map(({ text, path, target, amplitudeId }) => ( | ||
<MenuItem key={text} text={text} path={path} target={target} amplitudeId={amplitudeId} /> | ||
))} | ||
<MenuItem key="로그아웃" text="로그아웃" onClick={handleLogout} /> | ||
<MenuItem key="로그인완료" text={`${name}님`} className="amp-block" /> | ||
</> | ||
)} | ||
</ul> | ||
{onClickMenuToggle && isShown && <div className={dimmedBgVar[animation]} onClick={onClickMenuToggle} />} | ||
</nav> | ||
); | ||
}; | ||
|
||
export default MenuList; |
75 changes: 75 additions & 0 deletions
75
src/common/components/Layout/components/Header/Nav/MenuList/style.css.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { style, styleVariants } from '@vanilla-extract/css'; | ||
|
||
import { Z_INDEX } from '@constants/zIndex'; | ||
import { fadeIn, fadeInDown, fadeOut, fadeOutUp } from 'styles/animation.css'; | ||
import { theme } from 'styles/theme.css'; | ||
|
||
export const menuContainerVar = styleVariants({ | ||
open: { | ||
animation: `${fadeInDown} 0.3s`, | ||
}, | ||
close: { | ||
animation: `${fadeOutUp} 0.3s`, | ||
animationFillMode: 'forwards', | ||
}, | ||
}); | ||
export const menuList = style({ | ||
display: 'flex', | ||
alignItems: 'center', | ||
gap: 40, | ||
}); | ||
|
||
const menuMobList = style({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
gap: 18, | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
backgroundColor: theme.color.blackBackground, | ||
zIndex: Z_INDEX.gnbMenu, | ||
}); | ||
|
||
export const menuMobListVar = styleVariants({ | ||
TAB: [ | ||
menuMobList, | ||
{ | ||
padding: '92px 40px 40px 40px', | ||
}, | ||
], | ||
MOB: [ | ||
menuMobList, | ||
{ | ||
padding: '86px 20px 36px 20px', | ||
}, | ||
], | ||
}); | ||
|
||
export const dimmedBg = style({ | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100dvh', | ||
backgroundColor: theme.color.backgroundDimmed, | ||
zIndex: Z_INDEX.gnbBg, | ||
|
||
cursor: 'pointer', | ||
}); | ||
|
||
export const dimmedBgVar = styleVariants({ | ||
open: [ | ||
dimmedBg, | ||
{ | ||
animation: `${fadeIn} 0.3s`, | ||
}, | ||
], | ||
close: [ | ||
dimmedBg, | ||
{ | ||
animation: `${fadeOut} 0.3s`, | ||
animationFillMode: 'forwards', | ||
}, | ||
], | ||
}); |
24 changes: 24 additions & 0 deletions
24
src/common/components/Layout/components/Header/Nav/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { IconMenu, IconXClose } from '@sopt-makers/icons'; | ||
import { useContext } from 'react'; | ||
|
||
import { useDevice } from '@hooks/useDevice'; | ||
import { ThemeContext } from '@store/themeContext'; | ||
import { theme } from 'styles/theme.css'; | ||
|
||
import MenuList from './MenuList'; | ||
import { menuIconVar } from './style.css'; | ||
|
||
const Nav = ({ isMenuOpen, onClickMenuToggle }: { isMenuOpen: boolean; onClickMenuToggle: () => void }) => { | ||
const DEVICE_TYPE = useDevice(); | ||
const { isLight } = useContext(ThemeContext); | ||
|
||
return DEVICE_TYPE !== 'DESK' ? ( | ||
<i className={menuIconVar[DEVICE_TYPE]} onClick={onClickMenuToggle}> | ||
{isMenuOpen ? <IconXClose /> : <IconMenu color={isLight ? 'currentColor' : theme.color.white} />} | ||
</i> | ||
) : ( | ||
<MenuList /> | ||
); | ||
}; | ||
|
||
export default Nav; |
Oops, something went wrong.