File

src/app/admin/toolbar-notification/toolbar-notification.component.ts

Metadata

selector stbui-toolbar-notification
styleUrls ./toolbar-notification.component.scss
templateUrl ./toolbar-notification.component.html

Index

Properties
Methods
Inputs
Outputs
HostListeners

Constructor

constructor(_elementRef: ElementRef)
Parameters :
Name Type Optional
_elementRef ElementRef No

Inputs

notifications
Type : ToolbarNotificationModel[]
Default value : []

Outputs

delete
Type : EventEmitter

HostListeners

document:click
Arguments : '$event' '$event.target'
document:click(event: MouseEvent, targetElement: HTMLElement)

Methods

onDelete
onDelete(event, notification)
Parameters :
Name Optional
event No
notification No
Returns : void
toggleDropdown
toggleDropdown()
Returns : void

Properties

isOpen
Type : boolean
Default value : false
import {
  Component,
  ElementRef,
  HostListener,
  Input,
  Output,
  EventEmitter
} from '@angular/core';
import { ToolbarNotificationModel } from './toolbar-notification.model';

@Component({
  selector: 'stbui-toolbar-notification',
  templateUrl: './toolbar-notification.component.html',
  styleUrls: ['./toolbar-notification.component.scss']
})
export class ToolbarNotificationComponent {
  @Input() notifications: ToolbarNotificationModel[] = [];
  @Output() delete = new EventEmitter();
  isOpen: boolean = false;

  @HostListener('document:click', ['$event', '$event.target'])
  onClick(event: MouseEvent, targetElement: HTMLElement) {
    if (!targetElement) {
      return;
    }

    const clickedInside = this._elementRef.nativeElement.contains(
      targetElement
    );
    if (!clickedInside) {
      this.isOpen = false;
    }
  }

  constructor(private _elementRef: ElementRef) {}

  toggleDropdown() {
    this.isOpen = !this.isOpen;
  }

  onDelete(event, notification) {
    event.stopPropagation();

    this.delete.emit(notification);
  }
}
<div class="toolbar-notification-container">
  <button mat-icon-button (click)="toggleDropdown()">
    <mat-icon *ngIf="!notifications.length">notifications_none</mat-icon>
    <mat-icon [matBadge]="notifications?.length" matBadgeColor="primay" *ngIf="notifications.length">notifications_none</mat-icon>
  </button>

  <div class="dropdown mat-elevation-z2" [class.open]="isOpen">
    <div class="card">
      <div class="card-header">
        <div class="title">
          <div>通知</div>
          <div class="card-extra">您有 {{ notifications?.length }} 条新的通知</div>
        </div>
        <button type="button" mat-icon-button>
          <mat-icon>settings</mat-icon>
        </button>
      </div>
      <div *ngIf="notifications.length !== 0; then thenBlock else elseBlock;"></div>
      <div class="card-footer">
        <div class="card-action">查看所以通知</div>
      </div>
    </div>
  </div>
</div>

<ng-template #thenBlock>
  <perfect-scrollbar class="card-content">
    <mat-nav-list>
      <ng-container *ngFor="let notification of notifications; last as isLast">
        <mat-list-item>
          <mat-icon class="notice-icon-notifications" matListIcon>notifications</mat-icon>
          <h3 matLine> {{ notification.title }}</h3>
          <p matLine> {{ notification.lastTime }} </p>
          <button mat-icon-button (click)="onDelete($event, notification)">
            <mat-icon class="notice-icon-close">close</mat-icon>
          </button>
        </mat-list-item>
        <mat-divider *ngIf="!isLast"></mat-divider>
      </ng-container>
    </mat-nav-list>
  </perfect-scrollbar>
</ng-template>

<ng-template #elseBlock>
  <div class="no">暂无通知</div>
</ng-template>

./toolbar-notification.component.scss

.toolbar-notification {
  &-container {
    position: relative;
    display: flex;
    align-items: center;
  }
}

.dropdown {
  background: #fff;
  position: absolute;
  top: 55px;
  right: 0;
  min-width: 350px;
  z-index: 20;
  transform: translateY(-110%) scale(0);
  transform-origin: top right;
  visibility: hidden;
  transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
    visibility 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);

  @media screen and (max-width: 599px) {
    min-width: 100vw;
    right: -147px;
  }

  &.open {
    transform: translateY(0) scale(1);
    visibility: visible;
  }
}

.card {
  &-header {
    background: #eee;
    min-height: 54px;
    padding-left: 16px;
    padding-right: 16px;
    color: #555;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #e0e0e0;
  }

  &-extra {
    font-size: 12px;
    color: #888;
  }

  &-content {
    overflow: hidden;
    max-height: 256px;
  }

  &-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 42px;
    border-top: 1px solid #eee;
  }

  &-action {
    cursor: pointer;
    color: #aaa;
    text-align: center;
    font-size: 13px;
  }
}

.notice-icon-notifications {
  color: #888;
  border: 1px solid #eee;

  &.primary {
    background: #ccc;
    color: #ddd;
  }

  &.accent {
    background: #aaa;
    color: #bbb;
  }

  &.warn {
    background: #eee;
    color: #ddd;
  }

  &.read {
    color: #999;
  }
}

.no {
  padding: 20px;
  color: #ccc;
  display: flex;
  align-items: center;
  justify-content: center;
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""