Skip to content

Instantly share code, notes, and snippets.

@jcamilom
Created June 8, 2020 00:25
Show Gist options
  • Save jcamilom/27bb087a81fc36f6a4e268841ed03eaa to your computer and use it in GitHub Desktop.
Save jcamilom/27bb087a81fc36f6a4e268841ed03eaa to your computer and use it in GitHub Desktop.
[Side Menu] Angular side menu with slide up/down animation #angular #animations
/* #F16257 is p0 */
/* #ef493e is p0 -5% luminosity */
/* #ed3326 is p0 -10% luminosity */
/* #F1A157 is s0 */
:host {
display: flex;
flex-direction: column;
}
nav {
position: relative;
top: 88px;
}
.clickable {
cursor: pointer;
}
div.menu-item {
text-decoration: none;
color: white;
}
div.menu-item > span {
padding: 10px 10px 10px 20px;
}
div.menu-item > span:hover {
background-color: #ef493e;
}
div.menu-item.active > span {
background-color: #ef493e;
}
div.menu-item.active > span:hover {
background-color: #ed3326;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
padding: 10px 10px 10px 40px;
background-color: #ef493e;
}
li:hover {
background-color: #ed3326;
}
li.active {
background-color: #F1A157;
}
a {
text-decoration: none;
}
.logo {
position: fixed;
padding: 20px 20px 0px 20px;
background-color: #F16257;
z-index: 1;
width: 240px;
}
.logo img {
width: 95%;
height: 95%;
object-fit: cover;
overflow: hidden;
}
.logo hr {
color: white;
width: 100%;
height: 1px;
background-color: white;
border-width: 0;
}
<div class="logo" fxLayout="column">
<a routerLink="/" class="clickable">
<img src="assets/images/uniguajira-logo.png">
</a>
<hr>
</div>
<nav>
<div *ngFor="let item of MENU; index as i" class="menu-item clickable" [class.active]="!item.collapsed">
<span fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px" (click)="toggleItemCollapsed(i)">
<mat-icon>{{ item.icon }}</mat-icon>
<span>{{ item.label }}</span>
</span>
<ul *ngIf="!item.collapsed" [@slideUpDown]>
<li *ngFor="let subitem of item.children"
(click)="selectSubItem(subitem, item.label)" routerLink="{{subitem.path}}" routerLinkActive="active">
<a>{{ subitem.label }}</a>
</li>
</ul>
</div>
</nav>
import { Component, OnInit, EventEmitter, Output } from '@angular/core';
import { AppMenu, MenuSubitem } from 'src/app/models/menu';
import { AuthService } from 'src/app/core/services/auth/auth.service';
import { FULL_MENU } from 'src/app/consts/menu';
import {
trigger,
state,
style,
animate,
transition,
} from '@angular/animations';
@Component({
selector: 'app-side-menu',
templateUrl: './side-menu.component.html',
styleUrls: ['./side-menu.component.css'],
animations: [
trigger('slideUpDown', [
state('void', style({
height: 0,
opacity: 0,
})),
transition('void <=> *', [
animate('150ms ease-out')
])
])
]
})
export class SideMenuComponent implements OnInit {
public MENU: AppMenu;
public activeMenuIndex: number;
@Output() selected = new EventEmitter<{ submenu: MenuSubitem, parentName: string }>();
constructor(private authService: AuthService) { }
ngOnInit(): void {
this.createMenu();
}
private createMenu(): void {
const userPermissions = this.authService.userMenu;
this.MENU = [];
userPermissions.forEach(pLvlOne => {
const fullMenuLvlOne = FULL_MENU[pLvlOne.name];
const newMenuLvlOne = { ...fullMenuLvlOne, children: [] };
pLvlOne.children.forEach(pLvlTwo => {
const fullMenuLvlTwo = fullMenuLvlOne.children.find(fml2 => fml2.name === pLvlTwo.name);
const newMenuLvlTwo = { ...fullMenuLvlTwo, children: [] };
pLvlTwo.children.forEach(pLvlThree => {
const newItemLvlThree = fullMenuLvlTwo.children.find(fml3 => fml3.name === pLvlThree.name);
newMenuLvlTwo.children.push(newItemLvlThree);
});
newMenuLvlOne.children.push(newMenuLvlTwo);
});
this.MENU.push(newMenuLvlOne);
});
}
public toggleItemCollapsed(index: number) {
if (this.MENU[index].collapsed) { // clicked one was closed!
if (this.activeMenuIndex !== undefined) { // there was another one opened
this.MENU[this.activeMenuIndex].collapsed = !this.MENU[this.activeMenuIndex].collapsed; // close it!
}
this.activeMenuIndex = index; // mark the clicked one as the active one
} else { // clicked one was opended!
this.activeMenuIndex = undefined; // set none as the active one
}
// toggle the clicked one
this.MENU[index].collapsed = !this.MENU[index].collapsed;
}
public selectSubItem(menuSubitem: MenuSubitem, parentName: string): void {
this.selected.emit({
submenu: menuSubitem,
parentName
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment