Skip to content

Instantly share code, notes, and snippets.

@laudebugs
Last active October 5, 2022 20:11
Show Gist options
  • Save laudebugs/b4cd78384b5a477e5cc0303ebb778d2a to your computer and use it in GitHub Desktop.
Save laudebugs/b4cd78384b5a477e5cc0303ebb778d2a to your computer and use it in GitHub Desktop.
Ready to use collapsable side nav (in Angular with Angular Material)

Sometimes, all you need is a simple collapsible side nav with a bit of animation. I find myself writing a sidenave whenever I'm creating a lot of my web applications. So I refer to this more often as a quick place to start.

app.component.html:

<div class="main-container">
  <div mode="side" opened class="side-nav" [ngClass]="{collapsed}">
      <div class="menu">
        <div class="logo-container">
            <mat-icon class="button-icon">diversity_2</mat-icon>
            <h1 class="app-title" [ngClass]="{collapsed}">WebAppTitle</h1>
        </div>

          <nav>
              <!-- Add Navigation buttons or anything else here -->
          </nav>
      </div>
      <button class="toggle-collapse" mat-raised-button (click)="toggleCollapse()">
          {{ collapsed ? '' : 'Collapse' }}
          <mat-icon class="button-icon">{{ collapsed ? 'east' : 'west' }}</mat-icon>
      </button>
    </div>
  <div class="main-content" [ngClass]="{collapsed}">
    <router-outlet></router-outlet>
  </div>
</div>

app.component.scss:

$gray300: #e1e1e1;
:root {
  width: 100vw;
  height: 100vh;
}

div.main-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;

  .side-nav {
    width: 200px;
    height: 100%;
    overflow: hidden;
    border-right: 0.5px solid $gray300;

    &.collapsed {
      width: 75px;
    }
    .menu {
      height: 95%;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;

      .logo-container{
        display: flex;
        justify-content: space-evenly;
        flex-direction: row;
        align-items: center;
        height: 48px;
        .app-title{
          &.collapsed {
            display: none;
          }
        }
      }
    }
    .toggle-collapse {
      height: 5%;
      width: 100%;
      display: flex;
      justify-content: space-around;
      align-items: center;
      .button-icon {
        margin-left: 10px;
      }
      overflow: hidden;

    }
    transition: width 0.2s ease-in-out;

  }

  .main-content {
    margin-left: 200px;
    &.collapsed {
      margin-left: 75px;
    }
  }
}

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  #collapsed = JSON.parse(localStorage.getItem('collapsed') ?? 'false')

  get collapsed(): boolean {
      return this.#collapsed
  }
  set collapsed(value: boolean) {
      this.#collapsed = value
      localStorage.setItem('collapsed', JSON.stringify(value))
  }

  toggleCollapse(): void {
      this.collapsed = !this.collapsed
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment