mirror of
https://github.com/vercel/commerce.git
synced 2025-07-04 12:11:22 +00:00
🎨 styles: heade submenur responsive
:%s
This commit is contained in:
parent
6ab7b0ae97
commit
c65bf6aab7
@ -4,20 +4,28 @@
|
|||||||
@apply spacing-horizontal;
|
@apply spacing-horizontal;
|
||||||
padding-top: 4rem;
|
padding-top: 4rem;
|
||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
|
margin-bottom: 10rem;
|
||||||
.footerMenu {
|
.footerMenu {
|
||||||
padding-bottom: 8rem;
|
padding-bottom: 4rem;
|
||||||
}
|
}
|
||||||
.menu {
|
.menu {
|
||||||
@apply flex flex-wrap;
|
@apply flex flex-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@screen md {
|
@screen md {
|
||||||
|
margin-bottom: 0;
|
||||||
padding-bottom: 4rem;
|
padding-bottom: 4rem;
|
||||||
|
padding-left: 3.2rem;
|
||||||
|
padding-right: 3.2rem;
|
||||||
.footerMenu {
|
.footerMenu {
|
||||||
@apply flex;
|
@apply flex;
|
||||||
|
padding-bottom: 8rem;
|
||||||
.menu {
|
.menu {
|
||||||
@apply flex-nowrap justify-between;
|
@apply flex-nowrap justify-between;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@screen lg {
|
||||||
|
@apply spacing-horizontal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
margin-bottom: 1.6rem;
|
margin-bottom: 1.6rem;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
@apply transition-all duration-200 no-underline;
|
||||||
@apply transition-all duration-200;
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import React, { memo } from 'react'
|
|||||||
import HeaderHighLight from './components/HeaderHighLight/HeaderHighLight'
|
import HeaderHighLight from './components/HeaderHighLight/HeaderHighLight'
|
||||||
import HeaderMenu from './components/HeaderMenu/HeaderMenu'
|
import HeaderMenu from './components/HeaderMenu/HeaderMenu'
|
||||||
import HeaderSubMenu from './components/HeaderSubMenu/HeaderSubMenu'
|
import HeaderSubMenu from './components/HeaderSubMenu/HeaderSubMenu'
|
||||||
|
import HeaderSubMenuMobile from './components/HeaderSubMenuMobile/HeaderSubMenuMobile'
|
||||||
import s from './Header.module.scss'
|
import s from './Header.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -11,13 +12,16 @@ interface Props {
|
|||||||
|
|
||||||
const Header = memo(({ }: Props) => {
|
const Header = memo(({ }: Props) => {
|
||||||
return (
|
return (
|
||||||
<header className={s.header}>
|
<>
|
||||||
<HeaderHighLight />
|
<header className={s.header}>
|
||||||
<div className={s.menu}>
|
<HeaderHighLight />
|
||||||
<HeaderMenu />
|
<div className={s.menu}>
|
||||||
<HeaderSubMenu />
|
<HeaderMenu />
|
||||||
</div>
|
<HeaderSubMenu />
|
||||||
</header>
|
</div>
|
||||||
|
</header>
|
||||||
|
<HeaderSubMenuMobile />
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import Link from 'next/link'
|
|||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import InputSearch from 'src/components/common/InputSearch/InputSearch'
|
import InputSearch from 'src/components/common/InputSearch/InputSearch'
|
||||||
import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown'
|
import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown'
|
||||||
import { IconBuy, IconHistory, IconUser } from 'src/components/icons'
|
import { IconBuy, IconHeart, IconHistory, IconUser } from 'src/components/icons'
|
||||||
import { ACCOUNT_TAB, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
import { ACCOUNT_TAB, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
||||||
import s from './HeaderMenu.module.scss'
|
import s from './HeaderMenu.module.scss'
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ const HeaderMenu = memo(({ }: Props) => {
|
|||||||
<li>
|
<li>
|
||||||
<Link href={`${ROUTE.ACCOUNT}?${QUERY_KEY.TAB}=${ACCOUNT_TAB.FAVOURITE}`}>
|
<Link href={`${ROUTE.ACCOUNT}?${QUERY_KEY.TAB}=${ACCOUNT_TAB.FAVOURITE}`}>
|
||||||
<a >
|
<a >
|
||||||
<IconHistory />
|
<IconHeart />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
&:hover {
|
&:hover {
|
||||||
@apply text-primary;
|
@apply text-primary;
|
||||||
}
|
}
|
||||||
|
&.active {
|
||||||
|
@apply text-primary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
import classNames from 'classnames'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown'
|
import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown'
|
||||||
import { ProductFeature, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
import { ProductFeature, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
||||||
@ -32,23 +34,23 @@ const MENU = [
|
|||||||
const CATEGORY = [
|
const CATEGORY = [
|
||||||
{
|
{
|
||||||
name: 'Veggie',
|
name: 'Veggie',
|
||||||
link: `${ROUTE.PRODUCTS}?${QUERY_KEY.BRAND}=veggie`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=veggie`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Seafood',
|
name: 'Seafood',
|
||||||
link: `${ROUTE.PRODUCTS}?${QUERY_KEY.BRAND}=seafood`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=seafood`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Frozen',
|
name: 'Frozen',
|
||||||
link: `${ROUTE.PRODUCTS}?${QUERY_KEY.BRAND}=frozen`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=frozen`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Coffee Bean',
|
name: 'Coffee Bean',
|
||||||
link: `${ROUTE.PRODUCTS}?${QUERY_KEY.BRAND}=coffee-bean`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=coffee-bean`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Sauce',
|
name: 'Sauce',
|
||||||
link: `${ROUTE.PRODUCTS}?${QUERY_KEY.BRAND}=sauce`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=sauce`,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -56,14 +58,18 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const HeaderSubMenu = memo(({ }: Props) => {
|
const HeaderSubMenu = memo(({ }: Props) => {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={s.headerSubMenu}>
|
<section className={s.headerSubMenu}>
|
||||||
<ul className={s.menu}>
|
<ul className={s.menu}>
|
||||||
|
{/* todo: handle active item */}
|
||||||
<li>
|
<li>
|
||||||
<MenuDropdown options={CATEGORY} align="left">Categories</MenuDropdown>
|
<MenuDropdown options={CATEGORY} align="left">Categories</MenuDropdown>
|
||||||
</li>
|
</li>
|
||||||
{
|
{
|
||||||
MENU.map(item => <li key={item.name}>
|
MENU.map(item => <li key={item.name}
|
||||||
|
className={classNames({ [s.active]: router.asPath === item.link })}>
|
||||||
<Link href={item.link}>
|
<Link href={item.link}>
|
||||||
<a >
|
<a >
|
||||||
{item.name}
|
{item.name}
|
||||||
@ -73,7 +79,7 @@ const HeaderSubMenu = memo(({ }: Props) => {
|
|||||||
</li>)
|
</li>)
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
<HeaderNoti/>
|
<HeaderNoti />
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
@import "../../../../../styles/utilities";
|
||||||
|
|
||||||
|
.headerSubMenuMobile {
|
||||||
|
@apply fixed w-full bg-white;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
border-top: 1px solid var(--border-line);
|
||||||
|
box-shadow: -5px 6px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
.menu {
|
||||||
|
@apply grid grid-cols-4;
|
||||||
|
li {
|
||||||
|
a {
|
||||||
|
@apply transition-all duration-200 no-underline;
|
||||||
|
&:hover {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.menuItem {
|
||||||
|
@apply flex flex-col justify-center items-center sm-label;
|
||||||
|
.icon {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
svg path {
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
@apply text-primary;
|
||||||
|
}
|
||||||
|
&.dot {
|
||||||
|
.icon {
|
||||||
|
&::after {
|
||||||
|
@apply absolute bg-negative rounded-full;
|
||||||
|
content: "";
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
$size: 1rem;
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@screen md {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
import classNames from 'classnames'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { memo } from 'react'
|
||||||
|
import { IconHeart, IconHome, IconShopping, IconUser } from 'src/components/icons'
|
||||||
|
import { ACCOUNT_TAB, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
||||||
|
import s from './HeaderSubMenuMobile.module.scss'
|
||||||
|
|
||||||
|
const OPTION_MENU = [
|
||||||
|
{
|
||||||
|
link: ROUTE.HOME,
|
||||||
|
name: 'Home',
|
||||||
|
icon: <IconHome />,
|
||||||
|
isMarked: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
link: ROUTE.PRODUCTS,
|
||||||
|
name: 'Shopping',
|
||||||
|
icon: <IconShopping />,
|
||||||
|
isMarked: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
link: `${ROUTE.ACCOUNT}?${QUERY_KEY.TAB}=${ACCOUNT_TAB.FAVOURITE}`,
|
||||||
|
name: 'Favourites',
|
||||||
|
icon: <IconHeart />,
|
||||||
|
isMarked: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
link: ROUTE.ACCOUNT,
|
||||||
|
name: 'Account',
|
||||||
|
icon: <IconUser />,
|
||||||
|
isMarked: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const HeaderSubMenuMobile = memo(({ }: Props) => {
|
||||||
|
const router = useRouter()
|
||||||
|
return (
|
||||||
|
<header className={s.headerSubMenuMobile}>
|
||||||
|
<ul className={s.menu}>
|
||||||
|
{
|
||||||
|
OPTION_MENU.map(item => <li key={item.name}>
|
||||||
|
<Link href={item.link}>
|
||||||
|
<a >
|
||||||
|
<div className={classNames({
|
||||||
|
[s.menuItem]: true,
|
||||||
|
[s.dot]: item.isMarked,
|
||||||
|
[s.active]: router.pathname === item.link, // todo: handle active item
|
||||||
|
})}>
|
||||||
|
<span className={s.icon}>{item.icon}</span>
|
||||||
|
<span className={s.label}>{item.name}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</li>)
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</header>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default HeaderSubMenuMobile
|
@ -1,5 +1,6 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
const Vector = ({ ...props }) => {
|
const IconHeart = ({ ...props }) => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
@ -17,4 +18,4 @@ const Vector = ({ ...props }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Vector
|
export default IconHeart
|
11
src/components/icons/IconHome.tsx
Normal file
11
src/components/icons/IconHome.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const IconHome = () => {
|
||||||
|
return (
|
||||||
|
<svg width="18" height="21" viewBox="0 0 18 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M17.0001 7.00001L11.0001 1.74001C10.4501 1.24805 9.73803 0.976074 9.00009 0.976074C8.26216 0.976074 7.55012 1.24805 7.00009 1.74001L1.00009 7.00001C0.682463 7.28408 0.428995 7.63256 0.256567 8.02225C0.0841385 8.41194 -0.00329256 8.83389 9.47941e-05 9.26001V18C9.47941e-05 18.7957 0.316165 19.5587 0.878775 20.1213C1.44138 20.6839 2.20445 21 3.00009 21H15.0001C15.7957 21 16.5588 20.6839 17.1214 20.1213C17.684 19.5587 18.0001 18.7957 18.0001 18V9.25001C18.0021 8.82557 17.9139 8.40555 17.7416 8.01769C17.5692 7.62983 17.3165 7.28296 17.0001 7.00001ZM11.0001 19H7.00009V14C7.00009 13.7348 7.10545 13.4804 7.29299 13.2929C7.48052 13.1054 7.73488 13 8.00009 13H10.0001C10.2653 13 10.5197 13.1054 10.7072 13.2929C10.8947 13.4804 11.0001 13.7348 11.0001 14V19ZM16.0001 18C16.0001 18.2652 15.8947 18.5196 15.7072 18.7071C15.5197 18.8946 15.2653 19 15.0001 19H13.0001V14C13.0001 13.2044 12.684 12.4413 12.1214 11.8787C11.5588 11.3161 10.7957 11 10.0001 11H8.00009C7.20444 11 6.44138 11.3161 5.87877 11.8787C5.31616 12.4413 5.00009 13.2044 5.00009 14V19H3.00009C2.73488 19 2.48052 18.8946 2.29299 18.7071C2.10545 18.5196 2.00009 18.2652 2.00009 18V9.25001C2.00027 9.10802 2.03069 8.9677 2.08931 8.83839C2.14794 8.70907 2.23343 8.59372 2.3401 8.50001L8.34009 3.25001C8.52258 3.08969 8.75719 3.00127 9.00009 3.00127C9.243 3.00127 9.47761 3.08969 9.66009 3.25001L15.6601 8.50001C15.7668 8.59372 15.8523 8.70907 15.9109 8.83839C15.9695 8.9677 15.9999 9.10802 16.0001 9.25001V18Z" fill="#141414" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IconHome
|
11
src/components/icons/IconShopping.tsx
Normal file
11
src/components/icons/IconShopping.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const IconShopping = () => {
|
||||||
|
return (
|
||||||
|
<svg width="20" height="24" viewBox="0 0 20 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M18.167 6.16659H14.667V4.99992C14.667 3.76224 14.1753 2.57526 13.3002 1.70009C12.425 0.824917 11.238 0.333252 10.0003 0.333252C8.76265 0.333252 7.57566 0.824917 6.70049 1.70009C5.82532 2.57526 5.33366 3.76224 5.33366 4.99992V6.16659H1.83366C1.52424 6.16659 1.22749 6.2895 1.0087 6.50829C0.789909 6.72709 0.666992 7.02383 0.666992 7.33325V20.1666C0.666992 21.0948 1.03574 21.9851 1.69212 22.6415C2.3485 23.2978 3.23873 23.6666 4.16699 23.6666H15.8337C16.7619 23.6666 17.6522 23.2978 18.3085 22.6415C18.9649 21.9851 19.3337 21.0948 19.3337 20.1666V7.33325C19.3337 7.02383 19.2107 6.72709 18.9919 6.50829C18.7732 6.2895 18.4764 6.16659 18.167 6.16659ZM7.66699 4.99992C7.66699 4.38108 7.91282 3.78759 8.35041 3.35C8.78799 2.91242 9.38149 2.66659 10.0003 2.66659C10.6192 2.66659 11.2127 2.91242 11.6502 3.35C12.0878 3.78759 12.3337 4.38108 12.3337 4.99992V6.16659H7.66699V4.99992ZM17.0003 20.1666C17.0003 20.476 16.8774 20.7728 16.6586 20.9915C16.4398 21.2103 16.1431 21.3333 15.8337 21.3333H4.16699C3.85757 21.3333 3.56083 21.2103 3.34203 20.9915C3.12324 20.7728 3.00033 20.476 3.00033 20.1666V8.49992H5.33366V9.66659C5.33366 9.97601 5.45657 10.2728 5.67537 10.4915C5.89416 10.7103 6.19091 10.8333 6.50032 10.8333C6.80974 10.8333 7.10649 10.7103 7.32528 10.4915C7.54407 10.2728 7.66699 9.97601 7.66699 9.66659V8.49992H12.3337V9.66659C12.3337 9.97601 12.4566 10.2728 12.6754 10.4915C12.8942 10.7103 13.1909 10.8333 13.5003 10.8333C13.8097 10.8333 14.1065 10.7103 14.3253 10.4915C14.5441 10.2728 14.667 9.97601 14.667 9.66659V8.49992H17.0003V20.1666Z" fill="#141414" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IconShopping
|
@ -4,3 +4,6 @@ export { default as IconArrowRight } from './IconArrowRight'
|
|||||||
export { default as IconUser } from './IconUser'
|
export { default as IconUser } from './IconUser'
|
||||||
export { default as IconHistory } from './IconHistory'
|
export { default as IconHistory } from './IconHistory'
|
||||||
export { default as IconInfo } from './IconInfo'
|
export { default as IconInfo } from './IconInfo'
|
||||||
|
export { default as IconHome } from './IconHome'
|
||||||
|
export { default as IconShopping } from './IconShopping'
|
||||||
|
export { default as IconHeart } from './IconHeart'
|
||||||
|
@ -77,8 +77,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sm-label {
|
.sm-label {
|
||||||
font-size: 1rem;
|
font-size: 10px;
|
||||||
line-height: 1.6rem;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
.spacing-horizontal {
|
.spacing-horizontal {
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user