깜놀하는 해므찌로

앵귤러 사이드 메뉴 자동 닫힘 설정 angular side-menu / ng-container 본문

IT

앵귤러 사이드 메뉴 자동 닫힘 설정 angular side-menu / ng-container

agnusdei1207 2023. 6. 4. 11:24
반응형
SMALL
<div class="flex flex-col gap-1 select-none">
  <section
    class="flex justify-between items-center hover:bg-menuHover cursor-pointer rounded-xl px-5 py-3.5"
    [ngClass]="{
      'bg-menuHover': (menu.children && isChildrenOpen) || ( currentPath(menu)),
    }"
    (click)="handleItem(menu)"
  >
    <div class="flex items-center gap-3">
      <app-icon class="w-6 h-6" [name]="menu.icon"></app-icon>
      <div class="font-semibold">{{ menu.name }}</div>
    </div>
    <app-icon
      [ngClass]="{ 'rotate-180': isChildrenOpen }"
      class="w-6 h-6 transition-all"
      name="material-symbols:keyboard-arrow-down"
      *ngIf="menu.children && menu.children.length !== 0"
    ></app-icon>
  </section>
  <ng-container *ngIf="menu.children && isChildrenOpen">
    <section
      class="flex items-centerp gap-3 px-5 cursor-pointer bg-[#1A2D62] py-3.5 hover:bg-primary-350 rounded-xl"
      [ngClass]="{ 'bg-primary-350': currentChildren(children) }"
      (click)="handleChildren(children)"
      *ngFor="let children of menu.children"
    >
      <app-icon class="w-6 h-6" [name]="children.icon"></app-icon>
      <div>{{ children.name }}</div>
    </section>
  </ng-container>
</div>

1. menu 컴포넌트 템플릿입니다.

 

 

import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Router, RouterModule } from '@angular/router';
import { IonicModule } from '@ionic/angular';
import { IconComponent } from 'src/app/components/icon/icon.component';
import { Menu, MenuItem } from 'src/lib/menu';

@Component({
  selector: 'app-side-menu-item',
  templateUrl: './side-menu-item.component.html',
  styleUrls: ['./side-menu-item.component.scss'],
  standalone: true,
  imports: [CommonModule, RouterModule, IconComponent, IonicModule],
})
export class SideMenuItemComponent {
  @Output() selected: EventEmitter<Menu> = new EventEmitter<Menu>();

  @Input() menu!: Menu;
  isChildrenOpen: boolean = false;

  constructor(private router: Router) {}

  handleItem(menu: Menu) {
    if (menu.children && menu.children.length !== 0 && !this.isChildrenOpen) {
      this.isChildrenOpen = true;
      return;
    }
    this.isChildrenOpen = false;
    this.router.navigateByUrl(`/${menu.path}`);
    this.selected.emit(menu);
  }

  handleChildren(children: MenuItem) {
    if (this.menu) {
      this.router.navigateByUrl(`/${this.menu.path}/${children.path}`);
      this.selected.emit(this.menu);
    }
  }

  currentPath(menu: Menu): boolean {
    if (this.router.url.split('/').includes(menu.path)) return true;
    return false;
  }

  currentChildren(children: MenuItem): boolean {
    if (this.router.url.split('/').includes(children.path)) return true;
    return false;
  }
}

2. 메뉴 컴포넌트입니다.

 

 

 

 

 

<div
  class="px-5 flex flex-col gap-5 min-w-[15.75rem] max-w-[15.75rem] h-full bg-primary text-white py-7"
>
  <section class="flex items-center gap-2.5 pl-5">
    <ion-icon class="w-6 h-6" src="assets/icon/logo.svg"></ion-icon>
    <div class="font-semibold">안녕하세요?</div>
  </section>
  <div class="w-full border border-primary-450"></div>
  <section class="flex flex-col gap-1">
    <app-side-menu-item
      *ngFor="let menu of menus"
      [menu]="menu"
      (selected)="currentMenu.emit($event)"
    ></app-side-menu-item>
  </section>
  <div class="w-full border border-primary-450"></div>
</div>

 

3. 레이아웃 템플릿입니다. 위에 메뉴 컴포넌트를 이곳에서 반복합니다.

반응형
LIST