File

src/app/component/navigation/nav-collapse/nav-collapse.component.ts

Implements

OnInit

Metadata

encapsulation ViewEncapsulation.None
selector stbui-nav-collapse
styleUrls ./nav-collapse.component.scss
templateUrl ./nav-collapse.component.html

Index

Methods
Inputs
HostBindings

Constructor

constructor(service: NavigationService, router: Router)
Parameters :
Name Type Optional
service NavigationService No
router Router No

Inputs

item
Type : any

HostBindings

class
Default value : 'navigation-collapse navigation-item'
class.open
Default value : false

Methods

collapse
collapse()
Returns : void
expand
expand()
Returns : void
isChildrenOf
isChildrenOf(parent, item)
Parameters :
Name Optional
parent No
item No
Returns : any
isUrlInChildren
isUrlInChildren(parent, url)
Parameters :
Name Optional
parent No
url No
Returns : boolean
ngOnInit
ngOnInit()
Returns : void
toggleOpen
toggleOpen(e)
Parameters :
Name Optional
e No
Returns : void
import {
  Component,
  OnInit,
  Input,
  HostBinding,
  ViewEncapsulation
} from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { NavigationService } from '../navigation.service';
import { NavigationAnimation } from '../navigation.animation';

@Component({
  selector: 'stbui-nav-collapse',
  templateUrl: './nav-collapse.component.html',
  styleUrls: ['./nav-collapse.component.scss'],
  animations: NavigationAnimation,
  encapsulation: ViewEncapsulation.None
})
export class NavCollapseComponent implements OnInit {
  @Input()
  item: any;
  @HostBinding('class')
  classes = 'navigation-collapse navigation-item';
  @HostBinding('class.open')
  public isOpen = false;

  constructor(private service: NavigationService, private router: Router) {
    router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        if (this.isUrlInChildren(this.item, event.urlAfterRedirects)) {
          this.expand();
        } else {
          this.collapse();
        }
      }
    });

    this.service.onNavigationCollapseToggled.subscribe(clickedItem => {
      if (clickedItem && clickedItem.children) {
        if (this.isChildrenOf(this.item, clickedItem)) {
          return;
        }

        if (this.isUrlInChildren(this.item, this.router.url)) {
          return;
        }

        if (this.item !== clickedItem) {
          this.collapse();
        }
      }
    });
  }

  ngOnInit() {
    if (this.isUrlInChildren(this.item, this.router.url)) {
      this.expand();
    } else {
      this.collapse();
    }
  }

  toggleOpen(e) {
    e.preventDefault();

    this.isOpen = !this.isOpen;
    this.service.onNavigationCollapseToggled.emit(this.item);
    this.service.onNavigationCollapseToggle.emit();
  }

  expand() {
    if (this.isOpen) {
      return;
    }

    this.isOpen = true;
    this.service.onNavigationCollapseToggle.emit();
  }

  collapse() {
    if (!this.isOpen) {
      return;
    }
    this.isOpen = false;
    this.service.onNavigationCollapseToggle.emit();
  }

  isChildrenOf(parent, item) {
    if (!parent.children) {
      return false;
    }

    if (parent.children.indexOf(item) !== -1) {
      return true;
    }

    for (const children of parent.children) {
      if (children.children) {
        return this.isChildrenOf(children, item);
      }
    }
  }

  isUrlInChildren(parent, url) {
    if (!parent.children) {
      return false;
    }

    for (let i = 0; i < parent.children.length; i++) {
      if (parent.children[i].children) {
        if (this.isUrlInChildren(parent.children[i], url)) {
          return true;
        }
      }

      if (
        parent.children[i].url === url ||
        url.includes(parent.children[i].url)
      ) {
        return true;
      }
    }

    return false;
  }
}
<a (click)="toggleOpen($event)" class="navigation-link" matRipple>
  <mat-icon class="navigation-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
  <span class="navigation-link-title">{{item.title}}</span>
  <span class="navigation-link-badge" *ngIf="item.badge" [ngStyle]="{'background-color': item.badge.bg, 'color': item.badge.fg}">{{item.badge.title}}</span>
  <mat-icon class="navigation-collapse-arrow">keyboard_arrow_right</mat-icon>
</a>
<div class="navigation-children" [@slideInOut]="isOpen">
  <ng-container *ngFor="let item of item.children">
    <stbui-nav-item *ngIf="item.type=='item'" [item]="item"></stbui-nav-item>
    <stbui-nav-collapse *ngIf="item.type=='collapse'" [item]="item"></stbui-nav-collapse>
  </ng-container>
</div>

./nav-collapse.component.scss

.navigation {
  &-children {
    background: rgba(0, 0, 0, 0.12);
    color: rgba(255, 255, 255, 0.65);
    overflow: hidden;
  }

  &-collapse-arrow {
    font-size: 16px;
    width: 16px;
    height: 16px;

    transition: transform 0.25s;
    transform: rotate(0);
  }

  &-collapse {
    display: block;
    transition: transform 0.25s;

    &.open {
      > .navigation-link {
        &:before {
          content: ' ';
          position: absolute;
          left: 0;
          right: 0;
          bottom: 0;
          height: 2px;
          background: linear-gradient(180deg, rgba(0, 0, 0, 0.2), transparent);
        }
      }

      .navigation-collapse-arrow {
        transform: rotate(90deg);
      }
    }
  }
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""