UPDATE: Even after removing all references to TS functions from the HTML template, the issue persists. The problem remains even if I clear out the contents of the SCSS classes side-nav-submenu and submenu-open. However, the problem disappears when I remove the side-nav-submenu class from the ul.
I'm working on developing a mobile side navigation menu that consists of an unordered list with buttons as list items. Each button is followed by another unordered list which acts as a submenu. The submenu has height:auto; and max-height:0;, with transition effects set on max-height for expanding and contracting when toggled.
I've encountered a very peculiar and specific bug. If I open a submenu, then click on one of its buttons (which currently have no functionality), and then click anywhere else, the submenu mysteriously receives style="display: none;" in real-time according to the dev tools.
I'm puzzled because there is nothing in my code that explicitly sets display: none; on these submenus. My only guess is that Angular might be responsible, but I can't comprehend why. Here's a snippet of my code.
side-nav-mobile.component.html
<ul [class.nav-active]="navOpen" class="side-nav-menu-mobile">
<div (click)="toggleSubNav($event)">
<li id="inv" class="side-nav-button">Inventory <span class="menu-arrow" [class.arrow-down]="subNavOpen['inv']">›</span></li>
<ul class="side-nav-submenu">
<li>Add An Item</li>
<li>Inventory Search</li>
</ul>
<li id="cust" class="side-nav-button">Customers <span class="menu-arrow" [class.arrow-down]="subNavOpen['cust']">›</span></li>
<ul class="side-nav-submenu">
<li>Add New Customer</li>
<li>Awaiting Action</li>
</ul>
<li id="trans" class="side-nav-button">Transactions <span class="menu-arrow" [class.arrow-down]="subNavOpen['trans']">›</span></li>
<ul class="side-nav-submenu">
<li>Bill Of Sale</li>
</ul>
</div>
</ul>
side-nav-mobile.component.scss
@import "../../global-vars.scss";
.side-nav-menu-mobile {
display: inline-block;
background-color: $page-background-color;
left: -100%;
overflow: hidden;
height: 100vh;
width: 50%;
position: absolute;
transition: 0.25s ease-in-out;
z-index: 10;
margin: 0;
padding: 0;
}
.side-nav-menu-mobile > div {
margin-top: 3em;
}
.side-nav-menu-mobile > ul {
padding: 0;
margin: 0;
}
.side-nav-menu-mobile li {
list-style: none;
padding: 1em;
}
.side-nav-menu-mobile div > li {
width: calc(100% - 1em);
border-top: 1px solid $border-color;
border-bottom: 1px solid $border-color;
}
.side-nav-submenu {
height: auto;
max-height: 0;
overflow: hidden;
transition: max-height 0.15s linear;
padding-left: 1em;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.submenu-open {
// This is a temporary solution.
// Implement a better approach if available.
max-height: 8em;
}
.nav-active {
left: 0;
}
.menu-arrow {
display: inline-block;
transform: rotate(0);
transition: 0.15s ease-in;
}
.arrow-down {
transform: rotate(90deg);
}
@media screen and (min-width: 1200px) {
.side-nav-menu-mobile {
display: none;
}
}
side-nav-mobile.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-side-nav-mobile',
templateUrl: './side-nav-mobile.component.html',
styleUrls: ['./side-nav-mobile.component.scss']
})
export class SideNavMobileComponent implements OnInit {
navOpen: boolean = false;
subNavOpen: Object = {
inv: false,
cust: false,
trans: false
};
toggleSlide(): void {
this.navOpen = !this.navOpen;
}
toggleSubNav(event): void {
if(event.target.className.indexOf("side-nav-button") == -1) {
return;
}
if(event.target.nextElementSibling.className.indexOf("submenu-open") == -1) {
event.target.nextElementSibling.classList.add("submenu-open");
this.subNavOpen[event.target.id] = true;
} else {
event.target.nextElementSibling.classList.remove("submenu-open");
this.subNavOpen[event.target.id] = false;
}
}
constructor() { }
ngOnInit() {
}
}