Open juandc opened 3 years ago
Cree el componente del menu lateral, adicional lo importe en el componente Header, cree otro estado llamado toggleMobileMenu, a su vez en la imagen del menu en mobile le añadí un evento click y lo añadí encima de los otros 2 elementos modales, adicionalmente coloque en los estilos una posición absoluta, left de 0 para que flotará del lado izquierdo y le añadí un fondo blanco
mi solución quedo de la siguiente manera en header.jsx: ... const Header = () => { ... const [menuToggle, setMenuToggle] = useState(false);
const menuLeftToggle = () => {
setMenuToggle(!menuToggle);
console.log("entra")
}
return (
<nav>
<img src={menu} alt="menu" className="menu" onClick={menuLeftToggle}/>
...
<ul className={'menu-left' + (menuToggle ? '--active':'')}>
...
<div className={menuToggle ? 'settings-user' : ''}>
<div className='line'></div>
<a href="/">My orders</a>
<a href="/">My account</a>
<div className='user'>
<a className='user-email'>platzi@example.com</a>
<a className='singOut'>Sign out</a>
</div>
</div>
</ul>
y modificamos los estilos y sevea wuai
@media (max-width: 640px) { .menu { display: block; position:relative; } .navbar-left ul { display: none; } .navbar-left .menu-left--active{ display: block; height: 100vh; width: 60%; position: absolute; margin-top: 60px; background-color: var(--white); padding-top: 20px; float: left; margin-left: -45%; animation: swipeLeft .40s; font-weight: bold; overflow: scroll; } .navbar-left ul li { padding: 20px 30px; color: var(--black); } .navbar-left ul li a { color: var(--black); } .line { border: 1px solid var(--very-light-pink); width: 80%; margin-left: 14% ; opacity: 25%; } .settings-user { width: 100%; height: 80px; display: flex; flex-direction: column; } .settings-user a { padding: 20px 40px; text-decoration: none; color: var(--black); } .user { display: flex; flex-direction: column; margin-top: 20px; } .user a { padding: 8px 40px; } .user .user-email { font-weight: 500; } .user .singOut { color: var(--hospital-green); } .navbar-email { display: none; } @keyframes swipeLeft { 0% { width: 0; } 100% { width: 60%; } } }
Agregue el componente MobileMenu.jsx y sus respectivos estilos MobileMenu.scss.
En vez de agregar un nuevo estado en Header.jsx para el Menu Mobile, utilice el mismo del Menu Desktop, pero alternando el display mediante Media Query.
Se agrega lo siguiente en Header.jsx:
<img src={menuIcon} alt="menu" className="menu-icon" onClick={handleToggle}/>
{toggle && <MobileMenu/>}
Se agrega lo siguiente en Menu.scss:
@media (max-width: 640px) { .menu { display: none; } }
Comparto el componente y sus estilos MenuMobile.jsx ` import React from 'react'; import '../styles/MenuMobile.scss';
function MenuMobile() { return (
) }
export default MenuMobile; `
MenuMobile.scss ` @import 'vars';
.mobile-menu { background: var(--white); position: absolute; / add styles clase 19/ top: 45px; / add styles clase 19/ left: 0; width: 100%; padding: 12px 24px 24px 24px; / transition: 400ms; / display: none; z-index: 3; }
.mobile-menu a{ text-decoration: none; color: var(--black); font-weight: bold; }
.mobile-menu ul:not(.email-1){ padding: 0; margin: 24px 0 0; list-style: none; }
.mobile-menu ul:nth-child(1){ border-bottom: 1px solid var(--very-light-pink); }
.mobile-menu ul li{ margin-bottom: 22px; }
.mobile-menu .email{ font-size: var(--sm); font-weight: 300; }
.mobile-menu .sign-out{ font-size: var(--sm); color: var(--hospital-green); }
.email-1, #exp, #exp-1{ margin-bottom: 0; }
.email-1{ padding: 0; margin: 70px 0 0; list-style: none; }
@media (max-width: 640px) { .mobile-menu { display: inline-block; }
} `
Reto superado:
Mi código:
MenuMobile.jsx:
import React from 'react'
import '@styles/MenuMobile.scss'
import close from '@icons/icon_close.png'
function MenuMobile( { onCerrar } ) {
return (
<div className="mobile-menu">
<img src={close} alt="close menu" className="close" onClick={onCerrar} />
<div>
<ul>
<li><a href="/">CATEGORIES</a></li>
<li><a href="/">All</a></li>
<li><a href="/">Cloth</a></li>
<li><a href="/">Electronics</a></li>
<li><a href="/">Furniture</a></li>
<li><a href="/">Toys</a></li>
<li><a href="/">Others</a></li>
</ul>
<ul>
<li><a href="/">My orders</a></li>
<li><a href="/">My Account</a></li>
</ul>
</div>
<ul>
<li><a href="/" className="email">camilayokoo@gmail.com</a></li>
<li><a href="/" className="sign-out">Sign out</a></li>
</ul>
</div>
)
}
export default MenuMobile
MenuMobile.scss:
.mobile-menu-container {
position: fixed;
left: 0;
}
.mobile-menu {
position: fixed;
top: 60px;
bottom: 0;
left: 0;
height: calc(100% - 60px);
box-sizing: border-box;
width: 100%;
padding: 0 24px;
display: flex;
flex-direction: column;
justify-content: space-between;
background: var(--white);
opacity: 0.95;
}
.mobile-menu a {
text-decoration: none;
color: var(--black);
font-weight: bold;
}
.mobile-menu div {
margin: 0;
padding: 0;
width: 100%;
}
.mobile-menu ul {
padding: 0;
margin: 24px 0 0;
list-style: none;
}
.mobile-menu ul:nth-child(1) {
border-bottom: 1px solid var(--very-light-pink);
}
.mobile-menu ul:last-child {
margin-bottom: 28px;
}
.mobile-menu div ul li {
margin-bottom: 32px;
}
.mobile-menu .email {
font-size: var(--sm);
font-weight: 300;
margin-bottom: 4px;
display: inline-block;
}
.mobile-menu .sign-out {
color: var(--hospital-green);
font-size: var(--sm);
}
.mobile-menu .close {
position: absolute;
top: 8px;
right: 0px;
width: 16px;
object-fit: cover;
padding: 16px;
border-radius: 50%;
cursor: pointer;
}
Y los cambios en el Header.jsx:
import React, { useState, useContext, useRef } from 'react'
import '@styles/Header.scss'
import Menu from '@components/Menu'
import MyOrder from '@containers/MyOrder'
import MenuMobile from '@containers/MenuMobile'
import menu from '@icons/icon_menu.svg'
import logo from '@logos/logo_yard_sale.svg'
import AppContext from '@context/AppContext'
import shoppingCart from '@icons/icon_shopping_cart.svg'
const Header = () => {
const [toggle, setToggle] = useState(false)
const [toggleOrders, setToggleOrders] = useState(false)
const [toggleMenuMobile, setToggleMenuMobile] = useState(false)
const { state } = useContext(AppContext)
const handleToggle = () => {
setToggle(!toggle)
// setToggleOrders(false)
}
const handleToggleOrders = () => {
setToggleOrders(!toggleOrders)
// setToggle(false)
}
const handleToggleMenuMobile = () => {
setToggleMenuMobile(!toggleMenuMobile)
// setToggleMenuMobile(false)
}
const userMenu = useRef(null)
const menuMobile = useRef(null)
const asideMyOrder = useRef(null)
const closeOpenMenus = (e)=>{
if (userMenu.current && toggle && !userMenu.current.contains(e.target)) {
setToggle(false)
}
const navbarEmail = document.querySelector(".navbar-email")
if (asideMyOrder.current && toggleOrders && !asideMyOrder.current.contains(e.target) && e.target != navbarEmail) {
setToggleOrders(false)
}
if (menuMobile.current && toggleMenuMobile && !menuMobile.current.contains(e.target)) {
setToggleMenuMobile(false)
}
}
document.addEventListener('mousedown',closeOpenMenus)
return (
<nav>
<img src={menu} alt="menu" className="menu" onClick={handleToggleMenuMobile} />
<div className="navbar-left">
<img src={logo} alt="logo" className="nav-logo" />
<ul>
<li>
<a href="/">All</a>
</li>
<li>
<a href="/">Cloth</a>
</li>
<li>
<a href="/">Electronics</a>
</li>
<li>
<a href="/">Furniture</a>
</li>
<li>
<a href="/">Toys</a>
</li>
<li>
<a href="/">Others</a>
</li>
</ul>
</div>
<div className="navbar-right">
<ul>
<li className="navbar-email" onClick={handleToggle}>
user@example.com
</li>
<li
className="navbar-shopping-cart"
onClick={handleToggleOrders}
>
<img src={shoppingCart} alt="shopping cart" />
{state.cart.length > 0 ? <div>{state.cart.length}</div> : null}
</li>
</ul>
</div>
<div className="menu-container" ref={userMenu}>
{toggle && <Menu />}
</div>
<div className="my-order-container" ref={asideMyOrder}>
{toggleOrders && <MyOrder onCerrar = {() => setToggleOrders(false)} />}
</div>
<div className="mobile-menu-container" ref={menuMobile}>
{toggleMenuMobile && <MenuMobile onCerrar = {() => setToggleMenuMobile(false)} />}
</div>
</nav>
)
}
export default Header
Para más detalles los invito a revisar el código: https://github.com/Gustavolando/react-shop
Nota: En el reto anterior expliqué porqué comenté los setToogle
en los métodos handle
Ciao! Non abbiamo un menu mobile! 🇮🇹 🙀 🍕
¡No tenemos menú en mobile! ¡Debes agregarlo!
Recuerda que en el curso práctico de frontend developer creamos dos componentes diferentes del menú, uno para mobile y otro para desktop.
Ya logramos que el menú desktop aparezca con interacciones de los usuarios. Ahora debes encargarte de que el menú de la versión mobile aparezca y desaparezca cuando los usuarios presionen el ícono de menú en la navbar.
Para esto vas a requerir agregar nueva lógica en JavaScript y React.js, además de terminar de ajustar el CSS del menú.