We are facing a peculiar issue in our React application involving a sidebar and a bootstrap modal. The problem arises when we click the "X" button in the modal, causing the sidebar to momentarily drop down the page before the modal closes.
This strange behavior is only observed when clicking the "X" button, not any other button or input. Even when using the "Close" button, which performs the same action as the "X" button, the sidebar remains unaffected. The sidebar only moves when clicking and dragging the "X" button.
If the "X" button is clicked and the cursor is moved away before releasing the mouse button, the sidebar remains in the shifted position until the modal is closed.
We are puzzled by this behavior and would greatly appreciate any insights or assistance in resolving this issue.
Below is the code snippet for the React Component:
import React, { useContext, useEffect, useState, FC } from 'react'
import { NavLink } from 'react-router-dom'
import { BoxSeam, House, Check2Circle, Download } from 'react-bootstrap-icons'
import { GlobalContext } from '../context/GlobalContext'
import Header from '../components/Header'
import Snackbar from '../components/Snackbar'
import SelectLocationModal from '../components/SelectLocationModal'
import IPropsWithChildren from '../ts/interfaces/IPropsWithChildren.interface'
import INavLink from '../ts/interfaces/INavLink.interface'
import styles from '../styles/layouts/Layout.module.scss'
const PrivateLayout: FC<IPropsWithChildren> = ({ children }) => {
// Sidebar default is closed below 768px screens & open on larger
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const { location, setLocation } = useContext(GlobalContext);
const navLinks: INavLink[] = [
{
to: '/',
icon: <BoxSeam />,
displayText: 'Containers',
disabled: false
},
{
to: '/receiving',
icon: <Download />,
displayText: "Receiving",
disabled: false
},
{
to: '/approve',
icon: <Check2Circle />,
displayText: "Approve",
disabled: false
}
]
const closeOnSmScreen = () => {
setIsSidebarOpen(false);
}
useEffect(() => {
const location = localStorage.getItem('LocationID');
if (location) {
setLocation(location);
}
}, [setLocation])
return (
<div>
<SelectLocationModal
isOpen={location === ''}
handleClose={() => null}
/>
<Header
setIsSidebarOpen={setIsSidebarOpen}
isSidebarOpen={isSidebarOpen}
/>
<div className={styles.wrapper}>
<nav className={`${styles.sidebar} ${isSidebarOpen ? styles.active : ''} bg-light`}>
<div className={styles.sidebarContent}>
<ul className="ps-0">
{
navLinks.map((navLink, i) => (
<li key={i}>
<NavLink
to={ navLink.to }
activeClassName={ navLink.disabled ? '' : styles.activeLink }
className={`${navLink.disabled ? styles.disabledLink : ''} d-flex align-items-center flex-md-column py-2 navLink`}
onClick={closeOnSmScreen}
exact
>
{navLink.icon}
<span>{navLink.displayText}</span>
</NavLink>
</li>
))
}
</ul>
</div>
</nav>
<div className={"childrenContainer container"}>
{children}
<Snackbar />
</div>
</div>
</div>
)
}
export default PrivateLayout
And here is the corresponding CSS:
@import '../variables.scss';
.childrenContainer {
padding-top: $headerHeight;
}
.activeLink {
color: white !important;
background-color: $primary;
}
// Sidebar
.wrapper {
display: flex;
align-items: stretch;
width: 100%;
}
.sidebar {
position: fixed;
top: $headerHeight;
z-index: 999;
min-width: 85vw;
min-height: calc(100vh - #{$headerHeight});
margin-left: -85vw;
transition: .2s ease-in;
}
.sidebar.active {
margin-left: 0;
box-shadow: 2px 0px 15px 0px #000;
}
.sidebarContent {
position: sticky;
li {
list-style: none;
a {
text-decoration: none;
color: var(--dark);
}
}
}
.disabledLink {
text-decoration: line-through !important;
}
.navLink {
padding-left: 1rem;
span {
padding-left: .5rem;
}
svg {
height: 1.25rem;
width: 1.25rem;
}
}
@media screen and (min-width:768px) {
.childrenContainer {
padding-top: $headerLgHeight;
}
.sidebar {
position: sticky;
padding-top: $headerLgHeight;
margin-left: 0;
max-width: $sidebarWidth;
min-width: $sidebarWidth;
height: 100vh;
}
.sidebar.active {
margin-left: -$sidebarWidth;
box-shadow: none;
background: white !important;
}
.sidebarContent {
position: fixed;
width: $sidebarWidth;
}
.navLink {
display: flex;
flex-direction: column;
align-items: center;
padding-left: 0;
span {
padding-left: 0;
font-size: .67rem;
}
svg {
height: 1.25rem;
width: 1.25rem;
}
}
}
For a reproducible example, you can visit this code sandbox. Thank you to Igor Gonak for setting it up.