ng-devui
Version:
DevUI components based on Angular
311 lines (305 loc) • 20.3 kB
JavaScript
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { Component, Input, HostBinding, HostListener, Directive, NgModule } from '@angular/core';
import * as i1$1 from 'ng-devui/overlay-container';
import { OverlayContainerRef } from 'ng-devui/overlay-container';
import { PortalModule } from 'ng-devui/portal';
import * as i1 from 'ng-devui/position';
import { PositioningModule } from 'ng-devui/position';
import * as i2 from 'ng-devui/utils';
import { directionFadeInOut, WithConfig } from 'ng-devui/utils';
import { fromEvent, Subject } from 'rxjs';
import { __decorate, __metadata } from 'tslib';
import { map, debounceTime, filter, takeUntil } from 'rxjs/operators';
class TooltipComponent {
get position() {
return this._position;
}
set position(pos) {
this._position = pos;
this.currentPosition = Array.isArray(pos) ? pos[0] : pos;
}
get class() {
return 'devui-tooltip ' + this.currentPosition;
}
get state() {
return this.animateState;
}
get disabled() {
return !this.showAnimation;
}
constructor(positionService, tooltip, renderer2) {
this.positionService = positionService;
this.tooltip = tooltip;
this.renderer2 = renderer2;
this.showAnimation = true;
this.display = 'block';
}
ngAfterViewInit() {
this.updatePosition();
this.scrollElement = this.positionService.getScrollParent(this.triggerElementRef.nativeElement);
this._onScroll = fromEvent((this.scrollElement || window), 'scroll')
.subscribe(() => {
this.updatePosition();
});
}
ngOnDestroy() {
if (this._onScroll) {
this._onScroll.unsubscribe();
}
}
onShow() {
this.animateState = this.currentPosition;
}
onHide() {
this.animateState = 'void';
}
// will be overwrite by tooltip directive
onHidden() {
}
onAnimationEnd(event) {
if (event.toState === 'void') {
this.onHidden();
}
}
updatePosition() {
// 解决tooltip自身大小导致出现滚动条,影响位置计算
this.renderer2.setStyle(this.tooltip.nativeElement, 'visibility', 'hidden');
this.renderer2.setStyle(this.tooltip.nativeElement, 'transform', 'translate(0, -99999px)');
const rect = this.positionService.positionElements(this.triggerElementRef.nativeElement, this.tooltip.nativeElement, this.position, true);
setTimeout(() => {
this.currentPosition = rect.placementPrimary;
});
this.renderer2.setStyle(this.tooltip.nativeElement, 'left', `${rect.left}px`);
this.renderer2.setStyle(this.tooltip.nativeElement, 'top', `${rect.top}px`);
// 移除样式
this.renderer2.removeStyle(this.tooltip.nativeElement, 'visibility');
this.renderer2.removeStyle(this.tooltip.nativeElement, 'transform');
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipComponent, deps: [{ token: i1.PositionService }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TooltipComponent, selector: "d-tooltip", inputs: { content: "content", position: "position", triggerElementRef: "triggerElementRef", showAnimation: "showAnimation" }, host: { listeners: { "@directionFadeInOut.done": "onAnimationEnd($event)" }, properties: { "style.display": "this.display", "class": "this.class", "@directionFadeInOut": "this.state", "@.disabled": "this.disabled" } }, ngImport: i0, template: "<div class=\"devui-tooltip-arrow\"></div>\n<div class=\"devui-tooltip-inner\" [innerHTML]=\"content\"></div>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}:host-context(.devui-tooltip){position:absolute;z-index:var(--devui-z-index-pop-up, 1060);display:block;font-style:normal;font-weight:400;line-height:1.5;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:var(--devui-font-size, 12px);opacity:1}:host-context(.devui-tooltip) .devui-tooltip-arrow{display:block}:host-context(.devui-tooltip).top{margin-top:-5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).top .devui-tooltip-arrow{bottom:-5px;left:50%;transform:translate(-50%);border-width:5px 5px 0;border-top-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip).bottom{margin-top:5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).bottom .devui-tooltip-arrow{top:-5px;left:50%;transform:translate(-50%);border-width:0 5px 5px;border-bottom-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip).left{margin-left:-5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).left .devui-tooltip-arrow{top:50%;right:-5px;transform:translateY(-50%);border-width:5px 0 5px 5px;border-left-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip).right{margin-left:5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).right .devui-tooltip-arrow{top:50%;left:-5px;transform:translateY(-50%);border-width:5px 5px 5px 0;border-right-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip) .devui-tooltip-inner{max-width:200px;padding:4px 16px;font-size:var(--devui-font-size, 12px);color:var(--devui-feedback-overlay-text, #f0f0f0);letter-spacing:0;line-height:1.5;background:var(--devui-feedback-overlay-bg, #333333);box-shadow:none;overflow-wrap:break-word;word-break:break-word;word-wrap:break-word;text-align:start;border-radius:var(--devui-border-radius-feedback, 4px);min-height:26px}:host-context(.devui-tooltip) .devui-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}\n"], animations: [
directionFadeInOut
] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipComponent, decorators: [{
type: Component,
args: [{ selector: 'd-tooltip', animations: [
directionFadeInOut
], preserveWhitespaces: false, template: "<div class=\"devui-tooltip-arrow\"></div>\n<div class=\"devui-tooltip-inner\" [innerHTML]=\"content\"></div>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}:host-context(.devui-tooltip){position:absolute;z-index:var(--devui-z-index-pop-up, 1060);display:block;font-style:normal;font-weight:400;line-height:1.5;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:var(--devui-font-size, 12px);opacity:1}:host-context(.devui-tooltip) .devui-tooltip-arrow{display:block}:host-context(.devui-tooltip).top{margin-top:-5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).top .devui-tooltip-arrow{bottom:-5px;left:50%;transform:translate(-50%);border-width:5px 5px 0;border-top-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip).bottom{margin-top:5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).bottom .devui-tooltip-arrow{top:-5px;left:50%;transform:translate(-50%);border-width:0 5px 5px;border-bottom-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip).left{margin-left:-5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).left .devui-tooltip-arrow{top:50%;right:-5px;transform:translateY(-50%);border-width:5px 0 5px 5px;border-left-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip).right{margin-left:5px;padding:0;box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) rgba(var(--devui-text, #191919),.2)}:host-context(.devui-tooltip).right .devui-tooltip-arrow{top:50%;left:-5px;transform:translateY(-50%);border-width:5px 5px 5px 0;border-right-color:var(--devui-feedback-overlay-bg, #333333)}:host-context(.devui-tooltip) .devui-tooltip-inner{max-width:200px;padding:4px 16px;font-size:var(--devui-font-size, 12px);color:var(--devui-feedback-overlay-text, #f0f0f0);letter-spacing:0;line-height:1.5;background:var(--devui-feedback-overlay-bg, #333333);box-shadow:none;overflow-wrap:break-word;word-break:break-word;word-wrap:break-word;text-align:start;border-radius:var(--devui-border-radius-feedback, 4px);min-height:26px}:host-context(.devui-tooltip) .devui-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}\n"] }]
}], ctorParameters: () => [{ type: i1.PositionService }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { content: [{
type: Input
}], position: [{
type: Input
}], triggerElementRef: [{
type: Input
}], showAnimation: [{
type: Input
}], display: [{
type: HostBinding,
args: ['style.display']
}], class: [{
type: HostBinding,
args: ['class']
}], state: [{
type: HostBinding,
args: ['@directionFadeInOut']
}], disabled: [{
type: HostBinding,
args: ['@.disabled']
}], onAnimationEnd: [{
type: HostListener,
args: ['@directionFadeInOut.done', ['$event']]
}] } });
class TooltipDirective {
/**
* @deprecated Use showAnimation to replace.
*/
set showAnimate(isShowAnimate) {
this.showAnimation = isShowAnimate;
}
constructor(triggerElementRef, overlayContainerRef, componentFactoryResolver, devConfigService) {
this.triggerElementRef = triggerElementRef;
this.overlayContainerRef = overlayContainerRef;
this.componentFactoryResolver = componentFactoryResolver;
this.devConfigService = devConfigService;
this.position = 'top';
this.showAnimation = true;
// 防止每次鼠标不小心经过目标元素就会显示出Tooltip的内容,所以增加适当的延迟。
this.mouseEnterDelay = 150;
// 因为鼠标移出之后如果立刻消失会很突然,所以增加略小一些的延迟,使得既不突然也反应灵敏
this.mouseLeaveDelay = 100;
this.unsubscribe$ = new Subject();
this.unsubscribeT$ = new Subject();
}
onFocus() {
this.show();
}
onBlur() {
this.hide();
}
createTooltip() {
this.tooltipComponentRef = this.overlayContainerRef.createComponent(this.componentFactoryResolver.resolveComponentFactory(TooltipComponent));
this.instanceAssignValue(['content', 'position', 'showAnimation', 'triggerElementRef']);
// 对创建的ToolTip组件添加鼠标移入和移出的监听事件
if (this.tooltipComponentRef.instance.tooltip.nativeElement) {
this.bindMouseEvent(this.tooltipComponentRef.instance.tooltip.nativeElement, this.unsubscribeT$);
}
}
bindMouseEvent(eventTarget, unsubscribe$) {
fromEvent(eventTarget, 'mouseenter')
.pipe(map((event) => {
this.isEnter = true;
return event;
}), debounceTime(this.mouseEnterDelay), filter((event) => this.isEnter), takeUntil(unsubscribe$))
.subscribe(() => {
if (!this.tooltipComponentRef) {
this.show();
}
});
fromEvent(eventTarget, 'mouseleave')
.pipe(map((event) => {
this.isEnter = false;
return event;
}), debounceTime(this.mouseLeaveDelay), filter((event) => !this.isEnter), takeUntil(unsubscribe$))
.subscribe(() => {
this.hide();
});
}
show() {
if (!this.content) {
return;
}
if (this.tooltipComponentRef) {
this.destroy();
}
this.createTooltip();
this.tooltipComponentRef.instance.onShow();
}
destroy() {
if (this.tooltipComponentRef) {
this.tooltipComponentRef.destroy();
this.tooltipComponentRef = null;
}
if (this.unsubscribeT$) {
this.unsubscribeT$.next();
this.unsubscribeT$.complete();
}
}
hide() {
if (this.tooltipComponentRef) {
this.tooltipComponentRef.instance.onHide();
if (!this.showAnimation) {
this.destroy();
return;
}
this.tooltipComponentRef.instance.onHidden = () => {
this.destroy();
};
}
if (this.unsubscribeT$) {
this.unsubscribeT$.next();
this.unsubscribeT$.complete();
}
}
instanceAssignValue(key) {
const keyArr = typeof key === 'string' ? [key] : key;
const obj = {};
keyArr.forEach((item) => {
obj[item] = this[item];
});
Object.assign(this.tooltipComponentRef.instance, obj);
}
ngOnChanges(changes) {
if (this.tooltipComponentRef) {
const { content, position, showAnimation } = changes;
if (!content.currentValue) {
this.hide();
}
if (content) {
this.instanceAssignValue('content');
}
if (position) {
this.instanceAssignValue('position');
}
if (showAnimation) {
this.instanceAssignValue('showAnimation');
}
}
}
ngAfterViewInit() {
if (this.triggerElementRef.nativeElement) {
this.bindMouseEvent(this.triggerElementRef.nativeElement, this.unsubscribe$);
}
}
ngOnDestroy() {
if (this.unsubscribeT$) {
this.unsubscribeT$.next();
this.unsubscribeT$.complete();
}
this.unsubscribe$.next();
this.unsubscribe$.complete();
this.destroy();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipDirective, deps: [{ token: i0.ElementRef }, { token: i1$1.OverlayContainerRef }, { token: i0.ComponentFactoryResolver }, { token: i2.DevConfigService }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: TooltipDirective, selector: "[dTooltip]", inputs: { content: "content", position: "position", showAnimation: "showAnimation", showAnimate: "showAnimate", mouseEnterDelay: "mouseEnterDelay", mouseLeaveDelay: "mouseLeaveDelay" }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()" } }, exportAs: ["dTooltip"], usesOnChanges: true, ngImport: i0 }); }
}
__decorate([
WithConfig(),
__metadata("design:type", Object)
], TooltipDirective.prototype, "showAnimation", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipDirective, decorators: [{
type: Directive,
args: [{
selector: '[dTooltip]',
exportAs: 'dTooltip',
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1$1.OverlayContainerRef }, { type: i0.ComponentFactoryResolver }, { type: i2.DevConfigService }], propDecorators: { content: [{
type: Input
}], position: [{
type: Input
}], showAnimation: [{
type: Input
}], showAnimate: [{
type: Input
}], mouseEnterDelay: [{
type: Input
}], mouseLeaveDelay: [{
type: Input
}], onFocus: [{
type: HostListener,
args: ['focus']
}], onBlur: [{
type: HostListener,
args: ['blur']
}] } });
class TooltipModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: TooltipModule, declarations: [TooltipComponent, TooltipDirective], imports: [CommonModule,
PortalModule,
PositioningModule], exports: [TooltipComponent, TooltipDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipModule, providers: [
OverlayContainerRef,
], imports: [CommonModule,
PortalModule,
PositioningModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TooltipModule, decorators: [{
type: NgModule,
args: [{
imports: [
CommonModule,
PortalModule,
PositioningModule
],
exports: [TooltipComponent, TooltipDirective],
declarations: [TooltipComponent, TooltipDirective],
providers: [
OverlayContainerRef,
],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { TooltipComponent, TooltipDirective, TooltipModule };
//# sourceMappingURL=ng-devui-tooltip.mjs.map