UNPKG

bixi

Version:

企业级中后台前端解决方案

155 lines (141 loc) 4.06 kB
import { CdkConnectedOverlay } from '@angular/cdk/overlay'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; import { DEFAULT_TOOLTIP_POSITIONS, POSITION_MAP } from 'ng-zorro-antd/core/overlay'; import { ILabelingEvent, ISafeAny } from './label.type'; const OVERLAY_WIDTH = 468; const OVERLAY_HEIGHT = 288; @Component({ selector: 'bixi-label-modal', template: ` <div [ngStyle]="originStyle" cdkOverlayOrigin #trigger="cdkOverlayOrigin"> </div> <ng-template #overlay="cdkConnectedOverlay" cdkConnectedOverlayBackdropClass="bixi-label-modal-backdrop" cdkConnectedOverlay [cdkConnectedOverlayOrigin]="trigger" [cdkConnectedOverlayHasBackdrop]="true" [cdkConnectedOverlayPositions]="positions" [cdkConnectedOverlayOpen]="isOpen" [cdkConnectedOverlayPush]="true" [cdkConnectedOverlayMinHeight]="overlayHeight" [cdkConnectedOverlayMinWidth]="overlayWidth" [cdkConnectedOverlayOffsetX]="0" [cdkConnectedOverlayOffsetY]="-10" (backdropClick)="onClose()" (detach)="onDetach()" > <div class="bixi-label-modal" [ngStyle]="overlayStyle" cdkDrag [cdkDragBoundary]="dragBoundary || 'body'"> <div class="bixi-label-modal-header" cdkDragHandle> <div class='bixi-label-modal-header-inner'> <div class="bixi-label-modal-title">{{title}}</div> <div class="bixi-label-modal-close-icon" (click)="onClose()"> <i nz-icon nzType="close" nzTheme="outline"></i> </div> </div> </div> <div class="bixi-label-modal-content"> <ng-template [ngTemplateOutlet]="content" [ngTemplateOutletContext]="{$implicit: labeling, labeling: labeling, labels: labels, close: onClose }"> </ng-template> </div> </div> </ng-template> `, exportAs: 'bixiLabelModal', encapsulation: ViewEncapsulation.None, preserveWhitespaces: true, changeDetection: ChangeDetectionStrategy.OnPush }) export class BixiLabelModalComponent { overlayWidth = OVERLAY_WIDTH; overlayHeight = OVERLAY_HEIGHT; placement = 'right'; isOpen = false; _labeling: ILabelingEvent | null = null; @ViewChild('overlay', { static: false }) overlay!: CdkConnectedOverlay; @Input() content: TemplateRef<ISafeAny> | undefined; @Input() title: string; @Input() dragBoundary: string; @Input() set labeling(val: ILabelingEvent | null) { this._labeling = val; if (val) { this.onShow(); } else { this.onHide(); } } get labeling() { return this._labeling; } // tslint:disable-next-line: no-output-native @Output() close = new EventEmitter(); constructor( private cdr: ChangeDetectorRef ) { } get labels() { return this.labeling ? (this.labeling.data) || [] : []; } onShow() { if (this.isOpen && this.overlay) { // 如果是二次标注的话,只需要调整位置就可以了 Promise.resolve().then(() => { this.cdr.detectChanges(); this.overlay.overlayRef.updatePosition(); }); return; } this.isOpen = true; this.cdr.detectChanges(); } onHide() { this.isOpen = false; this.cdr.detectChanges(); } onClose = () => { this.onHide(); this.close.emit(); } onDetach() { // 其它方式关闭的话,也触发一次 cancel if (this.isOpen) { this.onClose(); } } get overlayStyle() { return { width: `${this.overlayWidth || 0}px`, height: `${this.overlayHeight || 0}px` }; } get positions() { return [POSITION_MAP[this.placement], ...DEFAULT_TOOLTIP_POSITIONS]; } get originStyle() { if (!this.labeling) { return { 'width': '0px', 'height': '0px' }; } return { position: 'absolute', width: '20px', height: '20px', top: `${this.labeling.position.top || 0}px`, left: `${this.labeling.position.left || 0}px` }; } }