diff --git a/src/App.tsx b/src/App.tsx index 15e35a9..a471ad4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,11 @@ +import './settings/styles/index.scss' + +import { Header } from './template/Header' + export function App() { - return
+ return ( + <> +
+ + ) } diff --git a/src/assets/icons/hamburger.svg b/src/assets/icons/hamburger.svg new file mode 100644 index 0000000..6cadeb3 --- /dev/null +++ b/src/assets/icons/hamburger.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/minicart.svg b/src/assets/icons/minicart.svg new file mode 100644 index 0000000..7db5dc8 --- /dev/null +++ b/src/assets/icons/minicart.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/search.svg b/src/assets/icons/search.svg new file mode 100644 index 0000000..e6e5a9c --- /dev/null +++ b/src/assets/icons/search.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/icons/x.svg b/src/assets/icons/x.svg new file mode 100644 index 0000000..e0e6d36 --- /dev/null +++ b/src/assets/icons/x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/m3-logo-medium.png b/src/assets/m3-logo-medium.png new file mode 100644 index 0000000..ea2bd14 Binary files /dev/null and b/src/assets/m3-logo-medium.png differ diff --git a/src/assets/m3-logo-small.png b/src/assets/m3-logo-small.png new file mode 100644 index 0000000..5536bc3 Binary files /dev/null and b/src/assets/m3-logo-small.png differ diff --git a/src/settings/styles/global/_config.scss b/src/settings/styles/global/_config.scss new file mode 100644 index 0000000..01079bd --- /dev/null +++ b/src/settings/styles/global/_config.scss @@ -0,0 +1,48 @@ +@use '../utils/resources/colors' as var; +@use '../utils/resources/fonts' as fonts; + +:root { + @each $name, $value in var.$clr-common { + --clr-common-#{$name}: #{$value}; + } + + --clr-primary-purple-500: #{map-get(var.$clr-primary-purple, '500')}; + --clr-primary-blue-500: #{map-get(var.$clr-primary-blue, '500')}; + + @each $name, $value in var.$clr-gray { + --clr-gray-#{$name}: #{$value}; + } + + --font-family-100: #{fonts.$font-family-100}; +} + +body { + font-family: var(--font-family-100); +} + +body { + --txt-xxs: 10px; + --txt-xs: 12px; + --txt-small: 13px; + --txt-normal: 14px; + --txt-medium: 16px; + --txt-large: 18px; + --txt-xl: 24px; + + @media screen and (min-width: 2500px) { + --txt-xxs: 20px; + --txt-xs: 24px; + --txt-small: 26px; + --txt-normal: 28px; + --txt-medium: 32px; + --txt-large: 36px; + --txt-xl: 48px; + } +} + +a, +input, +button, +textarea { + font-family: var(--font-family-100); +} diff --git a/src/settings/styles/global/_reset.scss b/src/settings/styles/global/_reset.scss new file mode 100644 index 0000000..b7ae335 --- /dev/null +++ b/src/settings/styles/global/_reset.scss @@ -0,0 +1,33 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +a { + text-decoration: none; +} + +li, +ol, +ul { + list-style: none; +} + +img { + display: block; + + max-width: 100%; + height: auto; +} + +input, +button { + border: none; + background-color: transparent; +} + +.btn-ref, +button { + cursor: pointer; +} diff --git a/src/settings/styles/global/exports.scss b/src/settings/styles/global/exports.scss new file mode 100644 index 0000000..a07e54a --- /dev/null +++ b/src/settings/styles/global/exports.scss @@ -0,0 +1,2 @@ +@import './reset'; +@import './config'; diff --git a/src/settings/styles/index.scss b/src/settings/styles/index.scss new file mode 100644 index 0000000..8862798 --- /dev/null +++ b/src/settings/styles/index.scss @@ -0,0 +1,2 @@ +@import './global/exports.scss'; +@import './utils/exports.scss'; diff --git a/src/settings/styles/utils/exports.scss b/src/settings/styles/utils/exports.scss new file mode 100644 index 0000000..026d749 --- /dev/null +++ b/src/settings/styles/utils/exports.scss @@ -0,0 +1,4 @@ +@import './resources/colors'; +@import './resources/fonts'; +@import './helpers/mixin'; +@import './helpers/functions'; diff --git a/src/settings/styles/utils/helpers/_functions.scss b/src/settings/styles/utils/helpers/_functions.scss new file mode 100644 index 0000000..751a46d --- /dev/null +++ b/src/settings/styles/utils/helpers/_functions.scss @@ -0,0 +1,7 @@ +@function fluid($width, $design-width) { + $width: calc($width / $design-width * 100); + + $width: quote($width + '%'); + + @return unquote($width); +} diff --git a/src/settings/styles/utils/helpers/_mixin.scss b/src/settings/styles/utils/helpers/_mixin.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/settings/styles/utils/resources/_colors.scss b/src/settings/styles/utils/resources/_colors.scss new file mode 100644 index 0000000..d4ffac0 --- /dev/null +++ b/src/settings/styles/utils/resources/_colors.scss @@ -0,0 +1,29 @@ +$clr-common: ( + 'black': #000, + 'white': #fff, + 'red': #ff0000, + 'green': #008000, +); + +$clr-primary-purple: ( + '500': #5200ff, +); + +$clr-primary-blue: ( + '500': #00c8ff, +); + +$clr-gray: ( + '100': #fafafa, + '150': #f0f0f0, + '200': #f2f2f2, + '300': #c7c7c7, + '400': #c4c4c4, + '450': #b8b7b7, + '500': #919191, + '600': #7d7d7d, + '700': #5e5e5e, + '800': #303030, + '900': #292929, + '1000': #110e0f, +); diff --git a/src/settings/styles/utils/resources/_fonts.scss b/src/settings/styles/utils/resources/_fonts.scss new file mode 100644 index 0000000..b8774db --- /dev/null +++ b/src/settings/styles/utils/resources/_fonts.scss @@ -0,0 +1 @@ +$font-family-100: 'Roboto', Arial, Helvetica, sans-serif; diff --git a/src/template/Header/index.module.scss b/src/template/Header/index.module.scss new file mode 100644 index 0000000..7442845 --- /dev/null +++ b/src/template/Header/index.module.scss @@ -0,0 +1,315 @@ +@use '../../settings/styles/utils/helpers/functions' as function; + +.header { + position: sticky; + top: 0; + left: 0; + + padding: 25px 0; + + background-color: var(--clr-common-black); +} + +.header { + @media only screen and (min-width: 1025px) { + padding: 25px 0 0; + } + + @media only screen and (min-width: 2500px) { + min-height: 162px; + } +} + +.content { + display: flex; + align-items: center; + justify-content: space-between; + + padding: 0px 16px; + margin-bottom: 27.14px; +} + +.content { + @media only screen and (min-width: 1025px) { + width: #{function.fluid(1080px, 1280px)}; + padding: 0; + margin: 0 auto 22px; + } + + @media only screen and (min-width: 2500px) { + width: #{function.fluid(2299.68px, 2500px)}; + } +} + +.logo { + @media only screen and (min-width: 1025px) { + width: function.fluid(136px, 1080px); + } + + @media only screen and (min-width: 2500px) { + width: function.fluid(265.62px, 2299.68px); + } +} + +.search { + display: flex; + align-items: center; + justify-content: center; + + min-height: 36px; + border: 2px solid var(--clr-gray-150); + border-radius: 5px; + + background-color: var(--clr-common-white); + + input { + width: 100%; + padding: 0 9px 0 16px; + min-height: 36px; + border-radius: 5px 0 0 5px; + + font-size: var(--txt-normal); + } +} + +.search { + button { + display: flex; + align-items: center; + justify-content: center; + + width: 36px; + height: 100%; + + background-color: var(--clr-common-white); + } +} + +.search { + @media only screen and (min-width: 1025px) { + button { + width: 50px; + } + } + + @media only screen and (min-width: 2500px) { + &, + input { + min-height: 57px; + } + + button { + width: 56.85px; + + img { + width: 35.15px; + height: 35.15px; + } + } + } +} + +.actions-top, +.actions-bottom { + display: flex; + align-items: center; + + a { + display: block; + font-size: var(--txt-normal); + text-transform: uppercase; + color: var(--clr-common-white); + transition: color 200ms linear; + + &:hover { + color: var(--clr-primary-blue-500); + } + } +} + +.actions-top { + gap: 55px; + + @media only screen and (min-width: 2500px) { + img { + width: 54.68px; + height: 54.68px; + } + } +} + +// remove open menu mobile button for large devices 1025 > x +.open { + display: flex; + + @media only screen and (min-width: 1025px) { + display: none; + } +} + +// remove action top link for small devices and added for large devices 1025 > x +.actions-top { + a { + display: none; + } + + @media only screen and (min-width: 1025px) { + a { + display: block; + } + } +} + +.menu { + @media only screen and (max-width: 1024px) { + position: fixed; + left: -100%; + top: 0; + + width: 100vw; + height: 100vh; + + background-color: transparent; + transition: 300ms ease; + + &-content { + width: function.fluid(988px, 1024px); + height: 100vh; + } + } +} + +.menu { + @media only screen and (max-width: 768px) { + &-content { + width: function.fluid(339px, 375px); + height: 100vh; + } + } +} + +.menu { + .actions-bottom { + width: 100%; + height: 78px; + + background-color: var(--clr-common-black); + } + + .list { + padding: 0 16px; + + a { + display: block; + text-transform: uppercase; + transition: color 200ms linear; + + &:hover { + color: var(--clr-primary-blue-500); + } + } + } +} + +.menu { + .list { + height: calc(100% - 78px); + padding-top: 31px; + + background-color: var(--clr-common-white); + + a { + margin-bottom: 12px; + + font-weight: 500; + font-size: var(--txt-normal); + + color: var(--clr-gray-400); + } + } +} + +.actions-bottom { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 16px; +} + +// styles for menu is active + +.menu { + &.active { + left: 0; + background-color: #0004; + } +} + +// menu styles for large devices 1025 > x +.menu { + @media only screen and (min-width: 1025px) { + display: block; + + width: 100%; + + .list { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 55px; + + padding: 14px 16px; + border-top: 1px solid var(--clr-common-white); + + background-color: var(--clr-common-black); + + a { + color: var(--clr-common-white); + margin: 0; + } + } + + background-color: var(--clr-common-black); + + .actions-bottom { + display: none; + } + } +} + +.search-top { + @media only screen and (min-width: 1025px) { + width: function.fluid(264px, 1080px); + } + + @media only screen and (min-width: 2500px) { + width: function.fluid(515.62px, 2299.68px); + } +} + +/*|[X]o-o-o-o[O]|*\ +|=| SEARCH BOXS |=| +\*|[O]o-o-o-o[X]|*/ + +//remove search top box for small, medium devices +.search-top { + display: none; + + @media only screen and (min-width: 1025px) { + display: flex; + } +} + +// added search bottom box for small devices, medium devices +.search-bottom { + display: flex; + padding: 0 16px; + + &-content { + width: 100%; + } + + @media only screen and (min-width: 1025px) { + display: none; + } +} diff --git a/src/template/Header/index.tsx b/src/template/Header/index.tsx new file mode 100644 index 0000000..85f97d3 --- /dev/null +++ b/src/template/Header/index.tsx @@ -0,0 +1,111 @@ +import logoImg from '../../assets/m3-logo-small.png' +import logoMediumImg from '../../assets/m3-logo-medium.png' +import searchIcon from '../../assets/icons/search.svg' +import cartIcon from '../../assets/icons/minicart.svg' +import openIcon from '../../assets/icons/hamburger.svg' +import closeIcon from '../../assets/icons/x.svg' + +import css from './index.module.scss' +import { HTMLAttributes, useMemo, useState } from 'react' + +interface SearchProps extends HTMLAttributes {} + +export function Search({ ...props }: SearchProps) { + return ( +
+ + +
+ ) +} + +export const Header = () => { + const [isOpenMenu, setIsOpenMenu] = useState(false) + + const handleOpen = useMemo( + () => + function () { + if (window.innerWidth <= 1024) setIsOpenMenu(true) + }, + [] + ) + + const handleClose = useMemo( + () => + function () { + if (window.innerWidth <= 1024) setIsOpenMenu(false) + }, + [] + ) + + return ( +
+ +
+ ) +}