forked from M3-Academy/desafio-react-e-typescript
feat(menu-mobile): Adiciona menu mobile funcional #3
11
package-lock.json
generated
11
package-lock.json
generated
@ -15,6 +15,7 @@
|
||||
"@types/node": "^16.18.11",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"classnames": "^2.3.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
@ -5402,6 +5403,11 @@
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
|
||||
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
|
||||
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
|
||||
},
|
||||
"node_modules/clean-css": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
|
||||
@ -20598,6 +20604,11 @@
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
|
||||
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
|
||||
},
|
||||
"classnames": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
|
||||
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
|
||||
|
@ -10,6 +10,7 @@
|
||||
"@types/node": "^16.18.11",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"classnames": "^2.3.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
|
4
src/assets/svgs/close-button.svg
Normal file
4
src/assets/svgs/close-button.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 |
16
src/atomo/DropDownItem.tsx
Normal file
16
src/atomo/DropDownItem.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
|
||||
interface Link {
|
||||
href: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
function DropDownItem(props: Link) {
|
||||
return (
|
||||
<li>
|
||||
<a href={props.href}>{props.text}</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
export { DropDownItem };
|
@ -3,15 +3,13 @@ import style from "./header-top.module.scss";
|
||||
import logo from "../assets/svgs/m3-logo.svg";
|
||||
import lupa from "../assets/svgs/lupa.svg";
|
||||
import cart from "../assets/svgs/buying-cart.svg";
|
||||
import menuIcon from "../assets/svgs/menu-hamburguer.svg";
|
||||
import { MenuHamburguer } from "./MenuHamburguer";
|
||||
|
||||
const HeaderTop = () => {
|
||||
return (
|
||||
<header className={style["header-top-container"]}>
|
||||
<div className={style["header-top-wrapper"]}>
|
||||
<figure className={style["menu-hamburger"]}>
|
||||
<img src={menuIcon} alt="Menu Mobile" />
|
||||
</figure>
|
||||
<MenuHamburguer />
|
||||
<figure className={style["m3-logo-wrapper"]}>
|
||||
<img className={style["m3-logo"]} src={logo} alt="M3 Ecommerce" />
|
||||
</figure>
|
||||
|
73
src/components/MenuHamburguer.tsx
Normal file
73
src/components/MenuHamburguer.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import "./header-bottom.module.scss";
|
||||
import style from "./header-top.module.scss";
|
||||
import menuIcon from "../assets/svgs/menu-hamburguer.svg";
|
||||
import closeButton from "../assets/svgs/close-button.svg";
|
||||
import { DropDownItem } from "../atomo/DropDownItem";
|
||||
import classnames from "classnames";
|
||||
|
||||
const MenuHamburguer = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const menuRef = useRef<HTMLDivElement>();
|
||||
const actualRef = menuRef.current;
|
||||
useEffect(() => {
|
||||
const handler = (e: any) => {
|
||||
if (actualRef) {
|
||||
if (!actualRef.contains(e.target)) {
|
||||
setOpen(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", handler);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", handler);
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={style["menu-container"]}
|
||||
ref={menuRef as React.MutableRefObject<HTMLDivElement>}
|
||||
>
|
||||
<div
|
||||
className={style["menu-trigger"]}
|
||||
onClick={() => {
|
||||
setOpen(!open);
|
||||
}}
|
||||
>
|
||||
<button className={style["menu-hamburger"]}>
|
||||
<img src={menuIcon} alt="Menu Mobile" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={classnames(
|
||||
style["dropdown-menu"],
|
||||
style[`${open ? "active" : "inactive"}`]
|
||||
)}
|
||||
>
|
||||
<div className={style["menu-top"]}>
|
||||
<button>ENTRAR</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
setOpen(!open);
|
||||
}}
|
||||
>
|
||||
<img src={closeButton} alt="Close button" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul className={style["menu-bottom"]}>
|
||||
<DropDownItem href={"/"} text={"CURSOS"} />
|
||||
<DropDownItem href={"/"} text={"SAIBA MAIS"} />
|
||||
<DropDownItem href={"/"} text={"INSTITUCIONAIS"} />
|
||||
</ul>
|
||||
|
||||
<div className={style["menu-overlay"]} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { MenuHamburguer };
|
@ -1,5 +1,13 @@
|
||||
@use "../variables.module.scss";
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.header-top-container {
|
||||
width: 100%;
|
||||
height: 76px;
|
||||
@ -31,8 +39,103 @@
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
.menu-hamburger {
|
||||
.menu-container {
|
||||
display: none;
|
||||
position: relative;
|
||||
|
||||
.menu-hamburger {
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
font-size: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
// display: none;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition: 0.5 ease;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: 0.5 ease;
|
||||
}
|
||||
|
||||
.menu-bottom,
|
||||
.menu-top {
|
||||
width: 96.484375%;
|
||||
min-width: 988px;
|
||||
padding: 31px 16px;
|
||||
}
|
||||
|
||||
.menu-top {
|
||||
background: variables.$color-black;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
button {
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: variables.$color-white;
|
||||
}
|
||||
|
||||
button {
|
||||
img {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
z-index: 40;
|
||||
}
|
||||
}
|
||||
|
||||
// &::after {
|
||||
// content: "";
|
||||
// background-image: url("../assets/svgs/close-button.svg");
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
.menu-bottom {
|
||||
background: variables.$color-white;
|
||||
height: 585px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: variables.$color-grey;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
|
||||
background-color: rgba(69, 69, 69, 0.7);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
display: block;
|
||||
|
Loading…
Reference in New Issue
Block a user