diff --git a/packages/web/src/components/common/header/Header.styles.ts b/packages/web/src/components/common/header/Header.styles.ts index f5b9b73ec..af1fc8e48 100644 --- a/packages/web/src/components/common/header/Header.styles.ts +++ b/packages/web/src/components/common/header/Header.styles.ts @@ -1,5 +1,6 @@ import { fonts } from "@constants/font.constant"; import styled from "@emotion/styled"; +import { media } from "@styles/media"; import mixins from "@styles/mixins"; import { Z_INDEX } from "@styles/zIndex"; @@ -9,35 +10,103 @@ export const HeaderWrapper = styled.header` position: fixed; z-index: ${Z_INDEX.fixed}; width: 100%; - height: 71px; gap: 10px; background-color: ${({ theme }) => theme.color.background01}; border-bottom: 1px solid ${({ theme }) => theme.color.border02}; `; +export const BottomNavWrapper = styled.nav` + ${mixins.flexbox("column", "center", "center")}; + width: 100%; + bottom: 0px; + position: fixed; + z-index: ${Z_INDEX.fixed}; + border-radius: 8px 8px 0px 0px; + backdrop-filter: blur(6px); + border: 1px solid ${({ theme }) => theme.color.border02}; + background-color: ${({ theme }) => theme.color.backgroundOpacity2}; +`; + +export const BottomNavContainer = styled.div` + ${mixins.flexbox("row", "center", "space-between")}; + max-width: 360px; + width: 100%; + padding: 0px 24px; +`; + +export const BottomNavItem = styled.div` + ${mixins.flexbox("row", "center", "center")}; + padding: 16px 8px; + + transition: color 0.3s ease; + ${mixins.flexbox("row", "center", "center")}; + ${fonts.body9}; + color: ${({ theme }) => theme.color.text04}; + &.selected, + &:hover { + color: ${({ theme }) => theme.color.text03}; + } +`; + export const HeaderContainer = styled.div` ${mixins.flexbox("row", "center", "space-between")}; max-width: 1440px; width: 100%; padding: 17px 40px; + ${media.tablet} { + max-width: 1180px; + padding: 12px 40px; + } + ${media.mobile} { + max-width: 360px; + padding: 8px 16px; + } `; export const LeftSection = styled.div` ${mixins.flexbox("row", "center", "flex-start")}; max-width: 895px; width: 100%; - height: 36px; gap: 50px; + ${media.tablet} { + max-width: 422px; + gap: 32px; + } + ${media.mobile} { + max-width: 21px; + } +`; + +export const LogoLink = styled.a` + .header-main-logo { + width: 31.501px; + height: 36px; + ${media.tablet} { + width: 28.001px; + height: 32px; + } + ${media.mobile} { + width: 21px; + height: 24px; + } + } `; export const Navigation = styled.nav` ${mixins.flexbox("row", "center", "flex-start")}; gap: 30px; + ${media.tablet} { + gap: 12px; + } ul { ${mixins.flexbox("row", "center", "center")}; gap: 40px; + ${media.tablet} { + gap: 16px; + } } li { + padding: 8px 0px; transition: color 0.3s ease; ${mixins.flexbox("row", "center", "center")}; ${fonts.body9}; @@ -46,29 +115,34 @@ export const Navigation = styled.nav` &:hover { color: ${({ theme }) => theme.color.text03}; } + ${media.tablet} { + padding: 8px 12px; + ${fonts.body11}; + } } `; -export const RightMenuWrapper = styled.div` - ${mixins.flexbox("row", "center", "flex-start")}; - gap: 30px; -`; - export const RightSection = styled.div` ${mixins.flexbox("row", "center", "flex-end")}; max-width: 255px; width: 100%; gap: 16px; + ${media.tablet} { + max-width: 231px; + gap: 8px; + } `; export const SearchContainer = styled.div` - ${mixins.flexbox("row", "center", "flex-end")}; - width: 100%; + ${mixins.flexbox("row", "center", "flex-start")}; gap: 18px; + ${media.tablet} { + gap: 10px; + } `; export const SearchButton = styled.button` - ${mixins.flexbox("row", "center", "flex-end")}; + ${mixins.flexbox("row", "center", "flex-start")}; border-radius: 4px; transition: all 0.3s ease; .search-icon { @@ -77,6 +151,10 @@ export const SearchButton = styled.button` * { fill: ${({ theme }) => theme.color.icon05}; } + ${media.tablet} { + width: 30px; + height: 30px; + } } &:hover { .search-icon * { @@ -85,14 +163,6 @@ export const SearchButton = styled.button` } `; -export const LogoLink = styled.a` - ${mixins.flexbox("row", "center", "center")}; - svg { - width: 32px; - height: 36px; - } -`; - export const ButtonWrapper = styled.button` ${mixins.flexbox("row", "center", "center")}; position: relative; diff --git a/packages/web/src/components/common/header/Header.tsx b/packages/web/src/components/common/header/Header.tsx index 13e54b009..09b5055ab 100644 --- a/packages/web/src/components/common/header/Header.tsx +++ b/packages/web/src/components/common/header/Header.tsx @@ -12,6 +12,9 @@ import { ButtonWrapper, SearchContainer, SearchButton, + BottomNavWrapper, + BottomNavContainer, + BottomNavItem, } from "./Header.styles"; import NotificationButton from "@components/common/notification-button/NotificationButton"; import { HEADER_NAV } from "@constants/header.constant"; @@ -19,6 +22,7 @@ import WalletConnectorButton from "@components/common/wallet-connector-button/Wa import HeaderSideMenuModal from "../header-side-menu-modal/HeaderSideMenuModal"; import { Token } from "@containers/header-container/HeaderContainer"; import SearchMenuModal from "../search-menu-modal/SearchMenuModal"; +import { DeviceSize } from "@styles/media"; interface HeaderProps { pathname?: string; @@ -32,6 +36,7 @@ interface HeaderProps { error: Error | null; search: (e: React.ChangeEvent) => void; keyword: string; + windowSize: Number; } const Header: React.FC = ({ @@ -45,58 +50,86 @@ const Header: React.FC = ({ isFetched, search, keyword, + windowSize, }) => { return ( - - - - - - - - - -
    + <> + + + + + + + + + + {windowSize > DeviceSize.mobile && ( + <> +
      + {HEADER_NAV.map(item => ( +
    • + {item.title} +
    • + ))} +
    + + ··· + + + )} +
    +
    + + + + + + + + + +
    + {windowSize <= DeviceSize.mobile && ( + + {HEADER_NAV.map(item => ( -
  • {item.title} -
  • + ))} -
- - ··· - -
-
- - - - - - - - - -
- {sideMenuToggle && ( - - )} - {searchMenuToggle && ( - - )} -
+ + + ··· + + + + )} + {sideMenuToggle && ( + + )} + {searchMenuToggle && ( + + )} + + ); }; export default Header; diff --git a/packages/web/src/components/common/notification-button/NotificationButton.styles.ts b/packages/web/src/components/common/notification-button/NotificationButton.styles.ts index 32d74def3..d8bb0fcde 100644 --- a/packages/web/src/components/common/notification-button/NotificationButton.styles.ts +++ b/packages/web/src/components/common/notification-button/NotificationButton.styles.ts @@ -1,4 +1,5 @@ import styled from "@emotion/styled"; +import { media } from "@styles/media"; import mixins from "@styles/mixins"; export const NotificationWrapper = styled.div` @@ -11,8 +12,17 @@ export const AlertButton = styled.button` height: 36px; border-radius: 4px; transition: all 0.3s ease; - .notification-icon * { - fill: ${({ theme }) => theme.color.icon05}; + .notification-icon { + width: 36px; + height: 36px; + padding: 4px; + ${media.tablet} { + width: 32px; + height: 32px; + } + * { + fill: ${({ theme }) => theme.color.icon05}; + } } &:hover { .notification-icon * { diff --git a/packages/web/src/components/common/wallet-connector-button/WalletConnectorButton.tsx b/packages/web/src/components/common/wallet-connector-button/WalletConnectorButton.tsx index 5fe8fa14a..0f8ee3d17 100644 --- a/packages/web/src/components/common/wallet-connector-button/WalletConnectorButton.tsx +++ b/packages/web/src/components/common/wallet-connector-button/WalletConnectorButton.tsx @@ -42,7 +42,6 @@ const WalletConnectorButton = ({ isConnected }: { isConnected: boolean }) => { height: 36, padding: "10px 16px", justify: "space-between", - // select: toggle.walletConnect, }} onClick={onMenuToggle} /> diff --git a/packages/web/src/constants/theme.constant.ts b/packages/web/src/constants/theme.constant.ts index 5804a6470..f3574e485 100644 --- a/packages/web/src/constants/theme.constant.ts +++ b/packages/web/src/constants/theme.constant.ts @@ -117,6 +117,7 @@ export const DARK_THEME_COLORS: ThemeColorType = { background15: colors.dark.blackBG, background16: colors.dark.gray200BG, backgroundOpacity: colors.dark.blackOpacity07BG, + backgroundOpacity2: colors.dark.blackOpacity07BG, backgroundGradient: colors.dark.gray600BG, backgroundGradient2: colors.global.gradient2, backgroundGradient3: colors.global.gradient3, @@ -188,6 +189,7 @@ export const LIGHT_THEME_COLORS: ThemeColorType = { background15: colors.white.gray100Opacity05BG, background16: colors.white.gray200BG, backgroundOpacity: colors.white.gray100Opacity05BG, + backgroundOpacity2: colors.white.whiteOpacity07BG, backgroundGradient: colors.white.gray100BG, backgroundGradient2: colors.white.gradient1, backgroundGradient3: colors.white.whiteBG, diff --git a/packages/web/src/containers/header-container/HeaderContainer.tsx b/packages/web/src/containers/header-container/HeaderContainer.tsx index 1026beb36..3ea34329e 100644 --- a/packages/web/src/containers/header-container/HeaderContainer.tsx +++ b/packages/web/src/containers/header-container/HeaderContainer.tsx @@ -2,7 +2,7 @@ /* eslint-disable */ import Header from "@components/common/header/Header"; import { useRouter } from "next/router"; -import React, { useState, useCallback } from "react"; +import React, { useState, useCallback, useEffect } from "react"; import { MATH_NEGATIVE_TYPE } from "@constants/option.constant"; import { type TokenDefaultModel } from "@models/token/token-default-model"; import { useQuery } from "@tanstack/react-query"; @@ -75,6 +75,18 @@ const HeaderContainer: React.FC = () => { const [sideMenuToggle, setSideMenuToggle] = useState(false); const [searchMenuToggle, setSearchMenuToggle] = useState(false); const [keyword, setKeyword] = useState(""); + const [width, setWidth] = useState(Number); + const handleResize = () => { + setWidth(window.innerWidth); + }; + + useEffect(() => { + handleResize(); + window.addEventListener("resize", handleResize); + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); const { isFetched, @@ -110,6 +122,7 @@ const HeaderContainer: React.FC = () => { error={error} search={search} keyword={keyword} + windowSize={width} /> ); }; diff --git a/packages/web/src/styles/ThemeTypes.ts b/packages/web/src/styles/ThemeTypes.ts index 65857a804..78d6daf55 100644 --- a/packages/web/src/styles/ThemeTypes.ts +++ b/packages/web/src/styles/ThemeTypes.ts @@ -18,6 +18,7 @@ export interface ThemeColorType { background15: string; background16: string; backgroundOpacity: string; + backgroundOpacity2: string; backgroundGradient: string; backgroundGradient2: string; backgroundGradient3: string;