Merge pull request 'feature/header' (#1) from feature/header into develop

Reviewed-on: #1
This commit is contained in:
Henrique Santos Santana 2022-12-28 04:13:03 +00:00
commit f03f393d4a
18 changed files with 585 additions and 1 deletions

View File

@ -1,3 +1,11 @@
import './settings/styles/index.scss'
import { Header } from './template/Header'
export function App() {
return <div className="App"></div>
return (
<>
<Header />
</>
)
}

View File

@ -0,0 +1,5 @@
<svg width="28" height="23" viewBox="0 0 28 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.25 19.0001H1.75002C0.783509 19.0001 0 19.7836 0 20.7501C0 21.7166 0.783508 22.5001 1.75002 22.5001H26.25C27.2165 22.5001 28 21.7166 28 20.7501C28 19.7836 27.2165 19.0001 26.25 19.0001Z" fill="white"/>
<path d="M26.25 9.5H1.75002C0.783509 9.5 0 10.2835 0 11.25C0 12.2165 0.783508 13 1.75002 13H26.25C27.2165 13 28 12.2165 28 11.25C28 10.2835 27.2165 9.5 26.25 9.5Z" fill="white"/>
<path d="M26.25 0H1.75002C0.783509 0 0 0.783509 0 1.75002C0 2.71652 0.783508 3.50003 1.75002 3.50003H26.25C27.2165 3.50003 28 2.71652 28 1.75002C28 0.783509 27.2165 0 26.25 0Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 688 B

View File

@ -0,0 +1,5 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M27.823 4.07236C27.6697 3.88079 27.4377 3.76928 27.1923 3.76928H5.69581L5.09469 1.16451C5.01009 0.798054 4.68377 0.538452 4.30768 0.538452H0.80768C0.361648 0.538452 0 0.9001 0 1.34619C0 1.79227 0.361648 2.15387 0.80768 2.15387H3.66516L7.7455 19.8355C7.83005 20.2019 8.15642 20.4615 8.53251 20.4615H24.7154C25.1614 20.4615 25.523 20.0999 25.523 19.6539C25.523 19.2078 25.1614 18.8462 24.7154 18.8462H9.17509L8.55384 16.1539H24.7693C25.1471 16.1539 25.4744 15.892 25.5573 15.5235L27.9803 4.75426C28.0342 4.51483 27.9763 4.26398 27.823 4.07236Z" fill="white"/>
<path d="M11.8461 21.5385C10.2131 21.5385 8.88452 22.867 8.88452 24.5C8.88452 26.133 10.213 27.4615 11.8461 27.4615C13.479 27.4615 14.8076 26.133 14.8076 24.5C14.8076 22.867 13.4791 21.5385 11.8461 21.5385Z" fill="white"/>
<path d="M21.5385 21.5385C19.9055 21.5385 18.5769 22.867 18.5769 24.5C18.5769 26.133 19.9054 27.4615 21.5385 27.4615C23.1714 27.4615 24.5 26.133 24.5 24.5C24.5 22.867 23.1715 21.5385 21.5385 21.5385Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,10 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3901_15)">
<path d="M13.2094 11.6187C14.0951 10.4091 14.6249 8.92334 14.6249 7.31267C14.6249 3.2807 11.3444 0.000183105 7.31245 0.000183105C3.28048 0.000183105 0 3.2807 0 7.31267C0 11.3446 3.28052 14.6252 7.31248 14.6252C8.92315 14.6252 10.409 14.0953 11.6186 13.2095L16.4092 18.0001L18 16.4093C18 16.4092 13.2094 11.6187 13.2094 11.6187ZM7.31248 12.3751C4.52086 12.3751 2.25001 10.1043 2.25001 7.31267C2.25001 4.52104 4.52086 2.25019 7.31248 2.25019C10.1041 2.25019 12.375 4.52104 12.375 7.31267C12.375 10.1043 10.1041 12.3751 7.31248 12.3751Z" fill="#303030"/>
</g>
<defs>
<clipPath id="clip0_3901_15">
<rect width="18" height="18" rx="5" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 804 B

4
src/assets/icons/x.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2284 1.28215L1.22996 10.9942C0.550673 11.6541 0.568968 12.7044 1.27083 13.3401C1.97268 13.9759 3.09232 13.9564 3.77161 13.2966L13.77 3.58449C14.4493 2.92466 14.431 1.87436 13.7292 1.23858C13.0273 0.602806 11.9077 0.622311 11.2284 1.28215Z" fill="white"/>
<path d="M1.65213 3.40819L10.8751 13.7186C11.5082 14.4263 12.6262 14.5239 13.3724 13.9366C14.1185 13.3493 14.2102 12.2995 13.5771 11.5918L4.35414 1.28143C3.72107 0.573715 2.603 0.476092 1.85686 1.06338C1.11072 1.65067 1.01906 2.70048 1.65213 3.40819Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 638 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -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);
}

View File

@ -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;
}

View File

@ -0,0 +1,2 @@
@import './reset';
@import './config';

View File

@ -0,0 +1,2 @@
@import './global/exports.scss';
@import './utils/exports.scss';

View File

@ -0,0 +1,4 @@
@import './resources/colors';
@import './resources/fonts';
@import './helpers/mixin';
@import './helpers/functions';

View File

@ -0,0 +1,7 @@
@function fluid($width, $design-width) {
$width: calc($width / $design-width * 100);
$width: quote($width + '%');
@return unquote($width);
}

View File

@ -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,
);

View File

@ -0,0 +1 @@
$font-family-100: 'Roboto', Arial, Helvetica, sans-serif;

View File

@ -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;
}
}

View File

@ -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<HTMLDivElement> {}
export function Search({ ...props }: SearchProps) {
return (
<div {...props}>
<input type="search" placeholder="Buscar..." />
<button type="button">
<img src={searchIcon} alt="Search icon" />
</button>
</div>
)
}
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 (
<header className={css.header}>
<nav className={css.nav}>
<div className={css.content}>
<button
onClick={handleOpen}
className={css.open}
type="button"
data-jsx="event"
>
<img src={openIcon} alt="ícone do botão para abrir o menu" />
</button>
<a className={css.logo} href="/">
<picture>
<source media="(min-width:1025px)" srcSet={logoMediumImg} />
<img src={logoImg} alt="logo da M3 Academy" />
</picture>
</a>
<Search className={`${css.search} ${css['search-top']}`} />
<div className={css['actions-top']}>
<a href="/">Entrar</a>
<button type="button">
<img src={cartIcon} alt="ícone de carrinho" />
</button>
</div>
</div>
<div className={`${css['search-bottom']}`}>
<Search className={`${css.search} ${css['search-bottom-content']}`} />
</div>
<div
className={`${css.menu} ${isOpenMenu ? css.active : ''}`}
data-jsx="target"
>
<div className={css['menu-content']}>
<div className={css['actions-bottom']}>
<a href="/">Entrar</a>
<button
onClick={handleClose}
className={css.close}
type="button"
data-jsx="event"
>
<img src={closeIcon} alt="ícone do botão para fechar o menu" />
</button>
</div>
<ul className={css.list}>
<li>
<a href="/">Cursos</a>
</li>
<li>
<a href="/">Saiba Mais</a>
</li>
<li>
<a href="/">Institucionais</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
)
}