Please refer Faq's page in documentation itself for queries and customization like Colors, RTL, Dark style..etc.
The following HTML,TS, CSS you should have in your page to implement a sidebar.
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { Component, ElementRef, HostListener, OnInit } from '@angular/core';
import { NavigationEnd, NavigationStart, Router } from '@angular/router';
import { fromEvent } from 'rxjs';
import { Menu, NavService } from '../../services/nav.service';
import { checkHoriMenu, parentNavActive, switcherArrowFn } from './sidemenu';
@Component({
selector: 'app-sidemenu',
templateUrl: './sidemenu.component.html',
styleUrls: ['./sidemenu.component.scss']
})
export class SidemenuComponent implements OnInit {
public menuItems!: Menu[];
public url: any;
public windowSubscribe$!: any;
constructor(
private router: Router,
private navServices: NavService,
public elRef: ElementRef,
private breakpointObserver: BreakpointObserver
) {
this.checkNavActiveOnLoad();
}
// To set Active on Load
checkNavActiveOnLoad() {
this.navServices.items.subscribe((menuItems) => {
this.menuItems = menuItems;
this.router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
const path = location.pathname.split('/');
const eventUrl = event.url.split('/');
if (path[path.length - 2] !== eventUrl[eventUrl.length - 2]) {
this.closeNavActive();
const sidelink = document.querySelectorAll('.side-menu__item.active');
const sidemenuul = document.querySelectorAll('.side-menu__item.has-sub');
const subSidemenuUl = document.querySelector('.slide-menu.active');
const subSidemenu = document.querySelectorAll('.nav-sub-link.sub-with-sub');
// sidemenuUl?.classList.remove('active');
subSidemenuUl?.classList.remove('active');
sidelink.forEach((e) => e.classList.remove('active'));
sidemenuul.forEach((e) => e.classList.remove('active'));
subSidemenu.forEach((e) => e.classList.remove('active'));
}
}
if (event instanceof NavigationEnd) {
menuItems.filter((items) => {
if (items.path === event.url) {
this.setNavActive(items);
}
if (!items.children) {
return false;
}
items.children.filter((subItems) => {
if (subItems.path === event.url) {
this.setNavActive(subItems);
}
if (!subItems.children) {
return false;
}
subItems.children.filter((subSubItems) => {
if (subSubItems.path === event.url) {
this.setNavActive(subSubItems);
}
if (!subSubItems.children) {
return false;
}
subSubItems?.children.filter((subSubItems1) => {
if (subSubItems1.path === event.url) {
this.setNavActive(subSubItems1);
}
if (!subSubItems1.children) {
return false;
}
return true;
});
return true;
});
return true;
});
return true;
});
setTimeout(() => {
if (
document.querySelector('body')?.classList.contains('horizontal-hover') && window.innerWidth > 992
) {
this.closeNavActive();
setTimeout(() => {
parentNavActive();
}, 0);
} else {
parentNavActive();
}
}, 200);
}
});
});
}
checkCurrentActive() {
this.navServices.items.subscribe((menuItems) => {
this.menuItems = menuItems;
const currentUrl = this.router.url;
menuItems.filter((items) => {
if (items.path === currentUrl) {
this.setNavActive(items);
}
if (!items.children) {
return false;
}
items.children.filter((subItems) => {
if (subItems.path === currentUrl) {
this.setNavActive(subItems);
}
if (!subItems.children) {
return false;
}
subItems.children.filter((subSubItems) => {
if (subSubItems.path === currentUrl) {
this.setNavActive(subSubItems);
}
});
return true;
});
return true;
});
});
}
//Active Nav State
setNavActive(item: Menu) {
this.menuItems.filter((menuItem) => {
if (menuItem !== item) {
menuItem.active = false;
this.navServices.collapseSidebar = false;
}
if (menuItem.children && menuItem.children.includes(item)) {
menuItem.active = true;
}
if (menuItem.children) {
menuItem.children.filter((submenuItems) => {
if (submenuItems.children && submenuItems.children.includes(item)) {
menuItem.active = true;
submenuItems.active = true;
}
if (submenuItems.children) {
submenuItems.children.forEach((subsubmenuItems) => {
if (
subsubmenuItems.children &&
subsubmenuItems.children.includes(item)
) {
menuItem.active = true;
submenuItems.active = true;
subsubmenuItems.active = true;
}
});
}
});
}
});
}
// Toggle menu
toggleNavActive(item:Menu) {
if (!item.active) {
this.menuItems.forEach((a:any) => {
if (this.menuItems.includes(item)) {
a.active = false;
}
if (!a.children) {
return false;
}
a.children.forEach((b:any) => {
if (a.children.includes(item)) {
b.active = false;
}
if (!b.children) {
return false;
}
b.children.forEach((c:any) => {
if (b.children.includes(item)) {
c.active = false;
}
if (!c.children) {
return false;
}
return true;
});
return true;
});
return true;
});
}
item.active = !item.active;
}
// Close Nav menu
closeNavActive() {
this.menuItems.forEach((a: any) => {
if (this.menuItems) {
a.active = false;
}
if (!a.children) {
return false;
}
a.children.forEach((b: any) => {
if (a.children) {
b.active = false;
}
});
return true;
});
}
ngOnInit(): void {
switcherArrowFn();
fromEvent(window, 'resize').subscribe(() => {
if (window.innerWidth >= 992) {
document.querySelector('body.horizontal')?.classList.remove('main-sidebar-show');
}
if (document.querySelector('body')?.classList.contains('horizontal-hover') && window.innerWidth > 992) {
const li = document.querySelectorAll('.side-menu li');
li.forEach((e) => {
e.classList.remove('is-expanded');
});
const ul = document.querySelectorAll('.side-menu ul');
ul.forEach((e) => {
e.classList.remove('open');
});
}
});
// detect screen size changes
this.breakpointObserver.observe(['(max-width: 991px)']).subscribe((result: BreakpointState) => {
if (result.matches) {
// small screen
this.checkCurrentActive();
} else {
// large screen
document.querySelector('body.horizontal')?.classList.remove('sidenav-toggled');
if (document.querySelector('.horizontal:not(.horizontal-hover)')) {
this.closeNavActive();
setTimeout(() => {
parentNavActive();
}, 100);
}
}
});
const vertical = document.querySelectorAll('#myonoffswitch1');
const horizontal = document.querySelectorAll('#myonoffswitch2');
const horizontalHover = document.querySelectorAll('#myonoffswitch111');
fromEvent(vertical, 'click').subscribe(() => {
this.checkCurrentActive();
});
fromEvent(horizontal, 'click').subscribe(() => {
this.closeNavActive();
});
fromEvent(horizontalHover, 'click').subscribe(() => {
this.closeNavActive();
});
const WindowResize = fromEvent(window, 'resize');
// subscribing the Observable
this.windowSubscribe$ = WindowResize.subscribe(() => {
checkHoriMenu();
});
const maincontent = document.querySelectorAll('.main-content');
fromEvent(maincontent, 'click').subscribe(() => {
if (document.querySelector('body')?.classList.contains('horizontal')) {
this.closeNavActive();
setTimeout(()=>{parentNavActive()}, 100);
}
});
}
scrolled: boolean = false;
@HostListener('window:scroll', [])
onWindowScroll() {
this.scrolled = window.scrollY > 74;
}
ngOnDestroy() {
// unsubscribing the Observable
this.windowSubscribe$.unsubscribe();
}
sidebarClose(){
if ((this.navServices.collapseSidebar = true)) {
document.querySelector('.app')?.classList.remove('sidenav-toggled');
this.navServices.collapseSidebar = false;
}
}
}