forked from M3-Academy/desafio-react-e-typescript
feat: criado menu para dispositivos moveis.
This commit is contained in:
parent
ad9bd24ab6
commit
eb9a32bc73
4
src/assets/svg/closeMenu.svg
Normal file
4
src/assets/svg/closeMenu.svg
Normal 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 |
Before Width: | Height: | Size: 688 B After Width: | Height: | Size: 688 B |
89
src/components/Header/Menu.css
Normal file
89
src/components/Header/Menu.css
Normal file
@ -0,0 +1,89 @@
|
||||
.menu-wrapper {
|
||||
position: absolute;
|
||||
/* O inset é uma abreviação do top, bottom, left e right juntos. */
|
||||
inset: 0;
|
||||
display: flex;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
div:has(> .menu-wrapper.false) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
div:has(> .menu-wrapper.false) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-wrapper.false {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-wrapper.opened {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.menu-content {
|
||||
z-index: 2;
|
||||
width: 90.5%;
|
||||
height: 585px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.menu-icon {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 280px) and (max-width: 1024px) {
|
||||
.menu-content {
|
||||
width: 95.30%;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-content-header {
|
||||
padding: 31px 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.menu-content-header a {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 16px;
|
||||
text-transform: uppercase;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menu-content-nav {
|
||||
background-color: #fff;
|
||||
height: 100%;
|
||||
padding: 31px 16px;
|
||||
}
|
||||
|
||||
.menu-content-nav li {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
text-transform: uppercase;
|
||||
color: #c4c4c4;
|
||||
}
|
||||
|
||||
.menu-content-nav li:nth-child(2) {
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.menu-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-color: #454545B2;
|
||||
z-index: 1;
|
||||
}
|
@ -1,8 +1,71 @@
|
||||
@import "../../styles/utils/variables.scss";
|
||||
|
||||
.menu {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-header-opacity {
|
||||
width: 100vw;
|
||||
min-height: 100%;
|
||||
opacity: 2;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: #454545b2;
|
||||
z-index: 999;
|
||||
|
||||
.menu-header {
|
||||
position: absolute;
|
||||
background-color: $black;
|
||||
width: 90.5%;
|
||||
|
||||
@media (min-width: 280px) and (max-width: 1024px) {
|
||||
width: 95.3%;
|
||||
}
|
||||
|
||||
.menu-header-wrapper {
|
||||
padding: 31px 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
div {
|
||||
a {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 16px;
|
||||
text-transform: uppercase;
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-nav {
|
||||
height: 585px;
|
||||
background-color: $white;
|
||||
padding: 31px 16px;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
text-transform: uppercase;
|
||||
color: $primary-500;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin: 12px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
// Bibliotecas
|
||||
import React from "react";
|
||||
import React, { useContext } from "react";
|
||||
|
||||
// Estilos
|
||||
import styleMenu from "./Menu.module.scss";
|
||||
import { MenuContext } from "./MenuContext";
|
||||
import { MenuOpened } from "./MenuOpened";
|
||||
|
||||
// Imagens
|
||||
import menu from "../../assets/svg/menu.svg";
|
||||
import openMenu from "../../assets/svg/openMenu.svg";
|
||||
|
||||
const Menu = () => {
|
||||
const { isOpened, setIsOpened } = useContext(MenuContext);
|
||||
|
||||
return (
|
||||
<div className={styleMenu["menu"]}>
|
||||
<img src={menu} alt="Menu"/>
|
||||
<div>
|
||||
<MenuOpened isOpened={isOpened} setIsOpened={setIsOpened} />
|
||||
|
||||
<img src={openMenu} alt="Abrir menu" onClick={() => setIsOpened(true)} className="menu-icon"/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
24
src/components/Header/MenuContext.tsx
Normal file
24
src/components/Header/MenuContext.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { createContext, useState } from "react";
|
||||
|
||||
interface MenuContextData {
|
||||
isOpened: boolean;
|
||||
setIsOpened: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
interface MenuContextChildren {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const MenuContext = createContext({} as MenuContextData);
|
||||
|
||||
export const MenuProvider: React.FC<MenuContextChildren> = ({ children }) => {
|
||||
const [isOpened, setIsOpened] = useState(false);
|
||||
|
||||
return (
|
||||
<MenuContext.Provider
|
||||
value={{ isOpened: isOpened, setIsOpened: setIsOpened }}
|
||||
>
|
||||
{children}
|
||||
</MenuContext.Provider>
|
||||
);
|
||||
};
|
47
src/components/Header/MenuOpened.tsx
Normal file
47
src/components/Header/MenuOpened.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import React from "react";
|
||||
|
||||
import "./Menu.css";
|
||||
|
||||
import menuClose from "../../assets/svg/closeMenu.svg";
|
||||
|
||||
interface MenuProps {
|
||||
isOpened: boolean;
|
||||
setIsOpened: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const MenuOpened = ({ isOpened, setIsOpened }: MenuProps) => {
|
||||
return (
|
||||
<div className={`menu-wrapper ${isOpened && "opened"}`}>
|
||||
<div className="menu-content">
|
||||
<div className="menu-content-header">
|
||||
<div>
|
||||
<a href="#entrar">Entrar</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<img
|
||||
src={menuClose}
|
||||
alt="Fechar menu"
|
||||
onClick={() => setIsOpened(false)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav className="menu-content-nav">
|
||||
<ul>
|
||||
<li>Cursos</li>
|
||||
<li>Saiba mais</li>
|
||||
<li>Institucionais</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="menu-overlay"
|
||||
onClick={() => setIsOpened(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { MenuOpened };
|
@ -2,12 +2,16 @@
|
||||
import React from "react";
|
||||
|
||||
// Componentes
|
||||
import { Menu } from "../components/header/Menu";
|
||||
// import { Menu } from "../components/header/Menu";
|
||||
import { Logo } from "../components/header/Logo";
|
||||
import { Form } from "../components/header/Form";
|
||||
import { User } from "../components/header/User";
|
||||
import { Nav } from "../components/header/Nav";
|
||||
|
||||
import { Menu } from "../components/header/Menu";
|
||||
|
||||
import { MenuProvider } from "../components/header/MenuContext";
|
||||
|
||||
// Estilos
|
||||
import styleHeaderWrapper from "../components/header/HeaderWrapper.module.scss";
|
||||
|
||||
@ -15,7 +19,10 @@ const Header = () => {
|
||||
return (
|
||||
<header>
|
||||
<div className={styleHeaderWrapper["headerWrapper"]}>
|
||||
<Menu />
|
||||
<MenuProvider>
|
||||
<Menu />
|
||||
</MenuProvider>
|
||||
|
||||
<Logo />
|
||||
<Form />
|
||||
<User />
|
||||
|
@ -5,6 +5,8 @@ import { Header } from "./Header";
|
||||
import { Section } from "./Section";
|
||||
import { Footer } from "./Footer";
|
||||
|
||||
|
||||
|
||||
function Home() {
|
||||
return (
|
||||
<body>
|
||||
|
Loading…
Reference in New Issue
Block a user