diff --git a/src/components/Header/Desktop/DesktopHeader.tsx b/src/components/Header/Desktop/DesktopHeader.tsx
index 663f9a5d..573a1860 100644
--- a/src/components/Header/Desktop/DesktopHeader.tsx
+++ b/src/components/Header/Desktop/DesktopHeader.tsx
@@ -1,11 +1,12 @@
import styled from '@emotion/styled';
import { colors } from '@sopt-makers/colors';
import Link from 'next/link';
+import { css } from '@emotion/react';
import { LOGO_IMAGE_URL } from '@src/assets/mainLogo/base64_logo';
import useHeader from '@src/hooks/useHeader';
import { GrowDown } from '@src/lib/styles/animation';
import { menuTapList } from '../menuTapList';
-import { MenuTapType, SingleMenuTap } from '../types';
+import { MenuTapType } from '../types';
function DesktopHeader() {
const { handleClickLogo, handleIsSelected } = useHeader();
@@ -18,7 +19,14 @@ function DesktopHeader() {
{menuTapList.map((menuTap) => (
-
+
+ {menuTap.title}
+
))}
@@ -26,35 +34,16 @@ function DesktopHeader() {
);
}
-type MenuTapProps = {
- menuTap: SingleMenuTap;
- handleIsSelected: (path: string | string[]) => boolean;
-};
-
-function MenuTap({ menuTap, handleIsSelected }: MenuTapProps) {
- switch (menuTap.type) {
- case MenuTapType.Anchor:
- return (
-
- {menuTap.title}
-
- );
- case MenuTapType.Router:
- return (
-
- {menuTap.title}
-
- );
- }
-}
-
interface MenuTitleProps {
isSelected?: boolean;
isOpened?: boolean;
+ menuColor: MenuTapType;
}
export const Wrapper = styled.div`
max-width: 1200px;
+ padding: auto 20px;
+ height: 100%;
width: 100%;
display: flex;
justify-content: space-between;
@@ -91,32 +80,12 @@ export const Logo = styled.button`
`;
export const MenuTitlesWrapper = styled.div`
- height: 100%;
-
display: flex;
align-items: center;
`;
-export const MenuTitleAnchor = styled(Link)`
- font-size: 18px;
- height: 100%;
- line-height: 36px;
- font-weight: 500;
- display: block;
- color: inherit;
- text-decoration: none;
- color: white;
- background-color: #504ebf;
- padding: 6px 32px;
- border-radius: 30px;
- &:hover {
- background-color: #413fac;
- }
-`;
-
export const MenuTitle = styled(Link)`
font-size: 18px;
- height: 100%;
line-height: 36px;
font-weight: ${({ isSelected }) => (isSelected ? '700' : '500')};
@@ -133,9 +102,20 @@ export const MenuTitle = styled(Link)`
top: 3.5rem; /* this is bad practice */
left: 0;
width: 100%;
- border-bottom: 2px solid ${colors.white};
+ border-bottom: ${({ menuColor }) =>
+ menuColor !== 'SPECIAL' ? `2px solid ${colors.white}` : 'none'};
}
}
+
+ ${({ menuColor }) =>
+ menuColor === 'SPECIAL' &&
+ css`
+ margin-left: 20px;
+ border-radius: 5.869px;
+ border: 1.027px solid #4786ff;
+ background: rgba(71, 134, 255, 0.28);
+ color: #267dff;
+ `}
`;
export default DesktopHeader;
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
index b6095b5a..520ffd59 100644
--- a/src/components/Header/Header.tsx
+++ b/src/components/Header/Header.tsx
@@ -1,3 +1,4 @@
+import { useEffect, useState } from 'react';
import { useIsDesktop, useIsMobile, useIsTablet } from '@src/hooks/useDevice';
import DesktopHeader from './Desktop/DesktopHeader';
import MobileHeader from './Mobile/MobileHeader';
@@ -8,8 +9,24 @@ export function Header() {
const isTablet = useIsTablet('768px', '939px');
const isMobile = useIsMobile();
+ const [isTransparent, setIsTransparent] = useState(false);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ const scrollPosition = window.scrollY;
+
+ scrollPosition <= 0 ? setIsTransparent(false) : setIsTransparent(true);
+ };
+
+ window.addEventListener('scroll', handleScroll);
+
+ return () => {
+ window.removeEventListener('scroll', handleScroll);
+ };
+ });
+
return (
-
+
{isDesktop && }
{isTablet && }
{isMobile && }
diff --git a/src/components/Header/Mobile/HeaderMenu.style.ts b/src/components/Header/Mobile/HeaderMenu.style.ts
index 4777fdcb..585b951a 100644
--- a/src/components/Header/Mobile/HeaderMenu.style.ts
+++ b/src/components/Header/Mobile/HeaderMenu.style.ts
@@ -3,6 +3,7 @@ import { colors } from '@sopt-makers/colors';
import Link from 'next/link';
import { css } from '@emotion/react';
import { FadeIn, FadeInDown, FadeOut, FadeOutUp } from '@src/lib/styles/animation';
+import { MenuTapType } from '../types';
type MenuType = 'idle' | 'open' | 'close';
@@ -12,6 +13,7 @@ interface CloseButtonProps extends RootProps {
interface MenuTitleProps {
isSelected?: boolean;
+ menuColor: MenuTapType;
}
interface RootProps {
@@ -29,8 +31,8 @@ export const Root = styled.div`
width: 100%;
height: 100vh;
- ${(props) => {
- switch (props.isMenuShown) {
+ ${({ isMenuShown }) => {
+ switch (isMenuShown) {
case 'open':
return css`
${FadeInDown()}
@@ -79,8 +81,8 @@ export const CloseButton = styled.button`
width: 28px;
height: 28px;
- ${(props) => {
- switch (props.isMenuShown) {
+ ${({ isMenuShown }) => {
+ switch (isMenuShown) {
case 'open':
return css`
${FadeIn}
@@ -141,11 +143,21 @@ export const MenuTitle = styled.div`
color: ${({ isSelected }) => (isSelected ? '#fff' : 'rgba(255, 255, 255, 0.5)')};
cursor: pointer;
+ width: fit-content;
&:not(:last-child) {
- padding-left: 30px;
- padding-right: 40px;
+ margin-left: 30px;
}
+
+ ${({ menuColor }) =>
+ menuColor === 'SPECIAL' &&
+ css`
+ padding: 0 20px;
+ border-radius: 5.869px;
+ border: 1.027px solid #4786ff;
+ background: rgba(71, 134, 255, 0.28);
+ color: #267dff;
+ `}
`;
export const Rules = styled(Link)`
diff --git a/src/components/Header/Mobile/HeaderMenu.tsx b/src/components/Header/Mobile/HeaderMenu.tsx
index e5880e01..2f81e2f9 100644
--- a/src/components/Header/Mobile/HeaderMenu.tsx
+++ b/src/components/Header/Mobile/HeaderMenu.tsx
@@ -2,7 +2,7 @@ import Link from 'next/link';
import { useEffect } from 'react';
import useHeader from '@src/hooks/useHeader';
import { menuTapList } from '../menuTapList';
-import { MenuState, MenuTapType, SingleMenuTap } from '../types';
+import { MenuState } from '../types';
import * as S from './HeaderMenu.style';
function useNoScroll(isMenuShown: MenuState) {
@@ -26,30 +26,6 @@ interface HeaderMenuProps {
handleHeaderToggleButton: () => void;
}
-type MenuTapProps = {
- menuTap: SingleMenuTap;
- handleIsSelected: (path: string) => boolean;
-};
-
-function MenuTap({ menuTap, handleIsSelected }: MenuTapProps) {
- switch (menuTap.type) {
- case MenuTapType.Anchor:
- return (
-
-
- {menuTap.title}
-
-
- );
- case MenuTapType.Router:
- return (
-
- {menuTap.title}
-
- );
- }
-}
-
function HeaderMenu({ isMenuShown, handleHeaderToggleButton }: HeaderMenuProps) {
useNoScroll(isMenuShown);
@@ -61,7 +37,13 @@ function HeaderMenu({ isMenuShown, handleHeaderToggleButton }: HeaderMenuProps)
{menuTapList.map((menuTap) => (
-
+
+ {menuTap.title}
+
))}
handleHeaderToggleButton()} />
diff --git a/src/components/Header/Mobile/MobileHeader.tsx b/src/components/Header/Mobile/MobileHeader.tsx
index 58502ca4..a84dbb49 100644
--- a/src/components/Header/Mobile/MobileHeader.tsx
+++ b/src/components/Header/Mobile/MobileHeader.tsx
@@ -1,4 +1,5 @@
import styled from '@emotion/styled';
+import { colors } from '@sopt-makers/colors';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { useState } from 'react';
@@ -19,7 +20,7 @@ function MobileHeader() {
return (
<>
-
+
router.push('/')} />
@@ -32,13 +33,16 @@ function MobileHeader() {
);
}
-export const StyledHeader = styled.div`
+export const StyledHeader = styled.div<{ isMenuShown: boolean }>`
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
z-index: 10;
- background-color: transparent;
+ background-color: ${({ isMenuShown }) => (isMenuShown ? colors.gray950 : 'initial')};
+ padding: 0 20px;
+ height: 100%;
+ transition: background-color 0.6s;
`;
export const Logo = styled.button`
diff --git a/src/components/Header/menuTapList.ts b/src/components/Header/menuTapList.ts
index a8bb1663..405b6874 100644
--- a/src/components/Header/menuTapList.ts
+++ b/src/components/Header/menuTapList.ts
@@ -2,28 +2,28 @@ import { MenuTapList, MenuTapType } from './types';
export const menuTapList: MenuTapList = [
{
- type: MenuTapType.Router,
- title: 'ABOUT',
+ type: MenuTapType.DEFAULT,
+ title: '소개',
href: '/about',
},
{
- type: MenuTapType.Router,
+ type: MenuTapType.DEFAULT,
title: '프로젝트',
href: '/project',
},
{
- type: MenuTapType.Router,
- title: '블로그',
+ type: MenuTapType.DEFAULT,
+ title: '활동 후기',
href: '/blog',
},
{
- type: MenuTapType.Router,
+ type: MenuTapType.DEFAULT,
title: '후원',
href: '/sponsor',
},
{
- type: MenuTapType.Router,
- title: '리크루팅',
+ type: MenuTapType.SPECIAL,
+ title: '지원하기',
href: '/recruit',
},
];
diff --git a/src/components/Header/style.ts b/src/components/Header/style.ts
index 586f067b..93699d71 100644
--- a/src/components/Header/style.ts
+++ b/src/components/Header/style.ts
@@ -1,29 +1,38 @@
import styled from '@emotion/styled';
-import { colors } from '@sopt-makers/colors';
+import { css } from '@emotion/react';
-export const Wrapper = styled.header`
+export const Wrapper = styled.header<{ isTransparent: boolean }>`
width: 100%;
min-height: 80px;
- margin: 0 auto;
+
display: flex;
justify-content: center;
align-items: center;
position: fixed;
- /* background-color: ${colors.gray950}; */
- /* backdrop-filter: blur(20px); */
z-index: 100;
- padding: 0 20px;
top: 0;
+ ${({ isTransparent }) =>
+ isTransparent &&
+ css`
+ background-color: rgba(0, 0, 0, 0.2);
+ backdrop-filter: blur(30px);
+ color: white;
+ `}
+
+ padding: 0 20px;
+
/* 태블릿 + 데스크탑 뷰 */
- @media (min-width: 768px) {
+ @media (max-width: 940px) and (min-width: 768px) {
height: 48px;
+ padding: 0;
}
/* 모바일 뷰 */
@media (max-width: 767px) {
height: 48px;
min-height: 48px;
+ padding: 0;
justify-content: space-between;
}
diff --git a/src/components/Header/types.ts b/src/components/Header/types.ts
index b1783b91..99fbf2c6 100644
--- a/src/components/Header/types.ts
+++ b/src/components/Header/types.ts
@@ -1,13 +1,12 @@
export type MenuState = 'idle' | 'open' | 'close';
export const enum MenuTapType {
- Router = 'ROUTER',
- Anchor = 'ANCHOR',
- Parent = 'PARENT',
+ DEFAULT = 'DEFAULT',
+ SPECIAL = 'SPECIAL',
}
export type SingleMenuTap = {
- type: MenuTapType.Router | MenuTapType.Anchor;
+ type: MenuTapType.DEFAULT | MenuTapType.SPECIAL;
title: string;
href: string;
};