I'm trying to fix some strange issue which appears on mobile devices. The problem is that when the user select link from the dropdown menu the close icon stucks and doesn't change with the hamburger menu icon. But when the user clicks on the hamburger menu and after that close the menu, then the close icon has been changed correctly with the hamburger menu icon.
Here is the code I'm using:
App.jsx
import React, { Suspense, useEffect, useState } from 'react';
import { Navigate, Route, Routes } from 'react-router';
import { useTranslation } from 'react-i18next';
import './i18n'
import Header from './components/Header';
import './App.css';
const App = () => {
const [hideMain, setHideMain] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [isMobile, setIsMobile] = useState(false);
const [selectedItem, setSelectedItem] = useState(localStorage.getItem("i18nextLng"));
const { t } = useTranslation();
const toggleClass = (e) => {
setIsOpen(!isOpen);
setHideMain(!hideMain);
};
useEffect(() => {
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
setIsMobile(true);
}
}, []);
return (
<div className="app">
<Suspense fallback={null}>
<header className="top-navbar">
<Header isMobile={isMobile} isOpen={isOpen} toggleClass={toggleClass} selectedItem= {selectedItem} setSelectedItem={setSelectedItem} />
</header>
</Suspense>
</div>
)
}
export default App;
Header.js
import { useEffect, useState } from "react";
import { Link, NavLink, useNavigate } from "react-router-dom";
import {
Button,
Row,
Col,
DropdownItem,
DropdownMenu,
DropdownToggle,
Nav,
Navbar,
UncontrolledDropdown,
Collapse,
NavItem
} from "reactstrap";
import i18next from "i18next";
import { useTranslation } from "react-i18next";
import Logo from '../../images/logo.png';
import { links } from "../../constants";
import './header.scss';
import { scrollToTop } from "../../utils";
function Header({ isMobile, isOpen, toggleClass, selectedItem, setSelectedItem }) {
const { t } = useTranslation();
const navigate = useNavigate();
const navigateToContact = () => {
navigate('/contact');
};
useEffect(() => {
if (isMobile && document.querySelectorAll('.container-fluid')[1]) {
document.querySelectorAll('.container-fluid')[1].classList.add("px-0");
}
}, [isMobile, isOpen])
return (
<>{!isMobile ? (<div className="container-fluid px-0">
<div className="mb-3">
<nav className="navbar navbar-expand-lg py-0">
<div className="container-fluid">
<NavLink onClick={scrollToTop} to="/truck-covers" className={`navbar-brand text-start ${!isMobile ? 'ms-4' : ''}`}>
<img src={Logo} alt="Pokrivala.net logo" className="w-50" />
</NavLink>
<div className="d-flex align-items-center justify-content-end collapse navbar-collapse" id="navbars-host">
<div className="social-icons me-3 text-end">
<Link to="https://www.facebook.com/brezentiruse" target="_blank">
<i className="fa-brands fa-facebook fs-4 mx-1 my-2 text-dark"></i>
</Link>
<Link to="https://www.facebook.com/CreativeIdeaGroup/?fref=ts" target="_blank">
<i className="fa-brands fa-facebook fs-4 text-dark"></i>
</Link>
</div>
<Button size="sm" color="dark" className="cursor-default me-2" outline>
<i className="fa fa-phone my-2 px-2" />+359 887 614 031
</Button>
<Button color="dark" size="sm" className="cursor-default me-2" outline>
<i className="fa fa-phone my-2 px-2" />+359 877 614 029
</Button>
<Button onClick={() => { scrollToTop(); navigateToContact(); }} color="dark" size="sm" className="location-link me-2" outline>
<Link className="text-dark text-decoration-none" to="/contact">
<i className="fa-solid fa-location-dot my-2 px-2" />{t('city')}
</Link>
</Button>
<Button color="dark" size="sm" outline className="cursor-default" href="mailto:[email protected]">
<i className="fa-solid fa-envelope my-2 px-2" />[email protected]
</Button>
<Navbar expand="sm" className="py-0">
<Nav className="ms-auto" navbar>
<UncontrolledDropdown setActiveFromChild className="cursor-pointer">
<DropdownToggle
caret
className="nav-link"
tag="a"
>
{selectedItem.toLocaleUpperCase()}
</DropdownToggle>
<DropdownMenu>
{selectedItem !== "en" && <DropdownItem
href="#"
tag="a"
onClick={() => {
i18next.changeLanguage('en');
setSelectedItem(localStorage.getItem("i18nextLng"));
}}
>
EN
</DropdownItem>
}
{selectedItem !== "bg" && <DropdownItem
href="#"
tag="a"
onClick={() => {
i18next.changeLanguage('bg');
setSelectedItem(localStorage.getItem("i18nextLng"));
}}
>
BG
</DropdownItem>}
{selectedItem !== "ro" && <DropdownItem
href="#"
tag="a"
onClick={() => {
i18next.changeLanguage('ro');
setSelectedItem(localStorage.getItem("i18nextLng"));
}}
>
RO
</DropdownItem>
}
</DropdownMenu>
</UncontrolledDropdown>
</Nav>
</Navbar>
</div>
</div>
</nav>
<nav className="navbar navbar-expand-md navbar-dark bc-blue">
<div className="collapse navbar-collapse align-items-center justify-content-center" id="navbarCollapse">
<ul className="navbar-nav ml-auto">
<li className="nav-item d-flex collapse navbar-collapse" id="navbars-host">
{links.map((element, i) => {
return (
<Col key={i}>
<NavLink
to={element.to}
className={({ isActive }) =>
isActive ? 'fw-bold' : ''
}
>
{t(element.name)}
</NavLink>
</Col>
)
})}
</li>
</ul>
</div>
</nav>
</div>
</div>) :
<Navbar expand="md" className={`small ${isOpen ? 'bc-blue' : ''}`}>
{!isOpen &&
<>
<NavLink onClick={scrollToTop} to="/truck-covers" className="navbar-brand text-start">
<img src={Logo} alt="Pokrivala.net logo" className="w-50" />
</NavLink>
<Navbar expand="sm" className="py-0 px-0 mt-5 me-2 text-end">
<Nav className=" ms-auto" navbar>
<UncontrolledDropdown setActiveFromChild className="cursor-notAllowed">
<DropdownToggle
caret
className="nav-link pointer-events-none"
tag="a"
>
{selectedItem.toLocaleUpperCase()}
</DropdownToggle>
<DropdownMenu>
{selectedItem !== "en" && <DropdownItem
href="#"
tag="a"
onClick={() => {
i18next.changeLanguage('en');
setSelectedItem(localStorage.getItem("i18nextLng"));
}}
>
EN
</DropdownItem>
}
{selectedItem !== "bg" && <DropdownItem
href="#"
tag="a"
onClick={() => {
i18next.changeLanguage('bg');
setSelectedItem(localStorage.getItem("i18nextLng"));
}}
>
BG
</DropdownItem>}
{selectedItem !== "ro" && <DropdownItem
href="#"
tag="a"
onClick={() => {
i18next.changeLanguage('ro');
setSelectedItem(localStorage.getItem("i18nextLng"));
}}
>
RO
</DropdownItem>
}
</DropdownMenu>
</UncontrolledDropdown>
</Nav>
</Navbar>
<div className="d-flex flex-column align-items-center text-start">
<Row className={`${isMobile ? '' : 'my-3'}`}>
<Col md="12" className={`${!isMobile ? '' : 'mt-3 mb-2'}`}>
<Button size="sm" color="dark" className="cursor-default me-2" outline>
<i className="fa fa-phone my-2 px-2" />+359 887 614 031
</Button>
</Col>
<Col className={`${!isMobile ? '' : 'mb-2'}`}>
<Button color="dark" size="sm" className="cursor-default me-2" outline>
<i className="fa fa-phone my-2 px-2" />+359 877 614 029
</Button>
</Col>
</Row>
</div>
<div className="d-flex flex-column align-items-center text-start">
<Row>
<Col md="12" className={`${!isMobile ? '' : 'mb-2'}`}>
<Button color="dark" size="sm" className="location-link me-2" outline>
<Link className="text-dark text-decoration-none" to="/contact">
<i className="fa-solid fa-location-dot my-2 px-2" />{t('city')}
</Link>
</Button>
</Col>
<Col className={`${!isMobile ? '' : 'mb-2'}`}>
<Button color="dark" size="sm" outline className="cursor-default">
<i className="fa-solid fa-envelope my-2 px-2" />[email protected]
</Button>
</Col>
</Row>
</div>
<div className="d-flex flex-column align-items-center text-start social-icons">
<Link to="https://www.facebook.com/brezentiruse" target="_blank">
<i className="fa-brands fa-facebook fs-4 mx-1 my-2 text-dark"></i>
</Link>
<Link to="https://www.facebook.com/CreativeIdeaGroup/?fref=ts" target="_blank">
<i className="fa-brands fa-facebook fs-4 text-dark"></i>
</Link>
</div>
</>
}
<div className={`menuToggle ${isOpen ? 'close' : ''}`} onClick={(e) => toggleClass(e)}>
<input type="checkbox" />
<span></span>
<span></span>
<span></span>
</div>
<Collapse isOpen={isOpen} navbar>
<Nav className="menu" navbar>
{links.map((element, i) => {
return (isOpen && <NavItem
onClick={({ target }) => {
target && target?.classList.toggle('active')
toggleClass(false);
}}
key={i}>
<NavLink to={element.to}>
{t(element.name)}
</NavLink>
</NavItem>)
})}
</Nav>
</Collapse>
</Navbar >
}
</>
)
};
export default Header;
header.scss
.cursor-pointer {
cursor: pointer;
}
.cursor-default {
cursor: default;
&:hover {
cursor: default;
}
}
// .cursor-notAllowed {
// cursor: not-allowed;
// }
// .pointer-events-none {
// pointer-events: none;
// }
.bc-blue {
background-color: #407AC7;
&.small {
position: fixed;
height: 100%;
width: 100%;
.container-fluid {
.navbar-expand-sm {
.container-fluid:nth-child(2) {
padding-left: 0;
padding-right: 0;
}
}
}
.navbar-brand {
position: absolute;
top: 3%;
}
li {
padding: 15px 0;
width: 100%;
&:hover::after,
&:focus::after {
background: #eee;
}
a {
font-size: 14px;
}
}
}
.active {
a {
font-weight: bold;
}
>.col>a {
font-weight: bold;
}
}
.col {
line-height: 100%;
}
a {
color: #fff;
text-decoration: none;
font-size: 13px;
text-transform: uppercase;
overflow: hidden;
width: 115px;
line-height: 1.45;
white-space: pre-line;
letter-spacing: 1px;
}
}
.location-link:hover {
background-color: #000 !important;
a {
color: #fff !important;
}
}
.menuToggle {
display: flex;
flex-direction: column;
position: absolute;
top: 7%;
right: 5%;
z-index: 1;
-webkit-user-select: none;
user-select: none;
&.close {
top: 3% !important;
}
input {
display: flex;
width: 40px;
height: 32px;
position: absolute;
cursor: pointer;
opacity: 0;
z-index: 2;
a {
text-wrap: wrap;
}
}
span {
display: flex;
width: 27px;
height: 2px;
margin-bottom: 5px;
position: relative;
background: #36383F;
border-radius: 12px;
z-index: 1;
transform-origin: 16.65px 2px;
transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1), background 0.5s cubic-bezier(0.77, 0.2, 0.05, 1), opacity 0.55s ease;
&:first-child {
transform-origin: 0% 0%;
}
}
}
.menuToggle .menuToggle span .menuToggle span:nth-last-child(2) {
transform-origin: 0% 100%;
}
.menuToggle input:checked~span {
opacity: 1;
transform: rotate(45deg) translate(-3px, -1px);
background: #36383F;
}
.menuToggle input:checked~span:nth-last-child(3) {
opacity: 0;
transform: rotate(0deg) scale(1, 1);
}
.menuToggle input:checked~span:nth-last-child(2) {
transform: rotate(-45deg) translate(0, -1px);
}
.menu {
position: absolute;
-webkit-font-smoothing: antialiased;
transform-origin: 0% 0%;
top: 53%;
left: 50%;
transform: translate(-50%, -52%);
transition: transform 0.3s cubic-bezier(0.77, 0.2, 0.05, 1.0);
width: 100%;
li {
padding: 15px 0;
transition-delay: 2s;
&.active {
&:focus,
&:active {
&::before {
content: '';
opacity: 50%;
}
}
color: #fff;
font-weight: bold;
background-color: #2E6DBF;
}
}
}
.menuToggle input:checked~ul {
transform: none;
}
To solve this issue I added to change the toggle state to false when the user selects item from the menu.
<Collapse isOpen={isOpen} navbar>
<Nav className="menu" navbar>
{links.map((element, i) => {
return (isOpen && <NavItem
onClick={({ target }) => {
target && target?.classList.toggle('active')
toggleClass(false); // here
}}
key={i}>
<NavLink to={element.to}>
t(element.name)}
</NavLink>
</NavItem>)
})}
</Nav>
</Collapse>
Thank you in advance!