ng-devui
Version:
DevUI components based on Angular
417 lines (410 loc) • 33.5 kB
JavaScript
import * as i4 from '@angular/common';
import { DOCUMENT, CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { Injectable, Component, Inject, HostBinding, EventEmitter, Directive, Input, Output, NgModule } from '@angular/core';
import * as i2$1 from 'ng-devui/overlay-container';
import { OverlayContainerRef } from 'ng-devui/overlay-container';
import * as i2 from 'ng-devui/position';
import { PositioningModule } from 'ng-devui/position';
import * as i5 from 'ng-devui/utils';
import { IsTemplateModule, SafePipeModule } from 'ng-devui/utils';
import * as i3 from 'ng-devui/i18n';
import { ReplaySubject, BehaviorSubject, fromEvent, Subscription } from 'rxjs';
import { debounceTime, throttleTime } from 'rxjs/operators';
import { throttle } from 'lodash-es';
class StepsGuideService {
constructor() {
this.showGuideSource = new ReplaySubject(1);
this.currentIndexSource = new BehaviorSubject(0);
this.showGuideObs = this.showGuideSource.asObservable();
this.currentIndex = this.currentIndexSource.asObservable();
// 引导步骤
this.steps = [];
this.currentStep = 0;
}
// 切换向导的显示和销毁
showGuide(visible) {
this.showGuideSource.next(visible);
}
setCurrentIndex(index) {
this.currentStep = index;
this.currentIndexSource.next(index);
}
getCurrentStep() {
return this.currentStep;
}
setSteps(steps) {
this.steps = steps;
}
getSteps() {
return this.steps;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideService, decorators: [{
type: Injectable
}] });
class StepsGuideComponent {
get class() {
return 'devui-step-item ' + this.position;
}
get display() {
return 'block';
}
constructor(stepService, renderer, positionService, elm, i18n, doc) {
this.stepService = stepService;
this.renderer = renderer;
this.positionService = positionService;
this.elm = elm;
this.i18n = i18n;
this.doc = doc;
this.position = 'top';
this.zIndex = 1100;
this.dots = [];
this.SCROLL_REFRESH_INTERVAL = 100;
this.DOT_HORIZONTAL_MARGIN = 27;
this.DOT_VERTICAL_MARGIN = 22;
this.document = this.doc;
}
ngOnInit() {
this.dots = new Array(this.stepsCount);
this.elm.nativeElement.style.zIndex = this.zIndex;
this.i18nCommonText = this.i18n.getI18nText().stepsGuide;
const i18nSubscription = this.i18n.langChange().subscribe((data) => {
this.i18nCommonText = data.stepsGuide;
});
this.subScriber = fromEvent(window, 'resize')
.pipe(debounceTime(this.SCROLL_REFRESH_INTERVAL))
.subscribe(() => {
this.updatePosition();
});
this.subScriber.add(i18nSubscription);
}
ngAfterViewInit() {
this.updatePosition();
if (!this.scrollElement) {
const currentScrollElement = this.positionService.getScrollParent(this.triggerElement);
this.scrollElement = currentScrollElement === this.document.body ? window : currentScrollElement;
}
const scrollSubscriber = fromEvent(this.scrollElement, 'scroll')
.pipe(throttleTime(this.SCROLL_REFRESH_INTERVAL, undefined, { leading: true, trailing: true }))
.subscribe(() => {
this.updatePosition();
});
this.subScriber.add(scrollSubscriber);
}
ngOnDestroy() {
if (this.subScriber) {
this.subScriber.unsubscribe();
}
}
updatePosition() {
const resPosition = this.position === 'right' ? 'right-top' : this.position;
const calcPosition = this.position === 'left' ? 'left-top' : resPosition;
const rect = this.positionService.positionElements(this.triggerElement, this.elm.nativeElement, calcPosition, true);
const targetRect = this.triggerElement.getBoundingClientRect();
let left = rect.left;
let top = rect.top;
switch (rect.placementPrimary) {
case 'top':
left = targetRect.left + this.triggerElement.clientWidth / 2 - this.elm.nativeElement.clientWidth / 2;
top = top + this.triggerElement.clientHeight / 2 - this.DOT_HORIZONTAL_MARGIN;
break;
case 'bottom':
left = targetRect.left + this.triggerElement.clientWidth / 2 - this.elm.nativeElement.clientWidth / 2;
top = top + this.DOT_HORIZONTAL_MARGIN / 2;
break;
case 'left':
left = left + this.triggerElement.clientWidth / 2 - this.DOT_HORIZONTAL_MARGIN;
top = top + this.triggerElement.clientHeight / 2 - this.DOT_VERTICAL_MARGIN;
break;
case 'right':
left = left - this.triggerElement.clientWidth / 2 + this.DOT_HORIZONTAL_MARGIN;
top = top + this.triggerElement.clientHeight / 2 - this.DOT_VERTICAL_MARGIN;
break;
default:
}
switch (rect.placementSecondary) {
case 'left':
left = targetRect.left;
break;
case 'right':
left = targetRect.left - this.elm.nativeElement.clientWidth + this.triggerElement.clientWidth;
break;
default:
}
this.renderer.setStyle(this.elm.nativeElement, 'left', `${left}px`);
this.renderer.setStyle(this.elm.nativeElement, 'top', `${top}px`);
if (this.leftFix) {
this.renderer.setStyle(this.elm.nativeElement, 'marginLeft', `${this.leftFix}px`);
}
if (this.topFix) {
this.renderer.setStyle(this.elm.nativeElement, 'marginTop', `${this.topFix}px`);
}
}
next() {
const newStep = (this.stepIndex + 1 < this.stepsCount && this.stepIndex + 1) || this.stepsCount - 1;
this.stepService.setCurrentIndex(newStep);
this.close(newStep, 'next');
}
prev() {
const newStep = (this.stepIndex - 1 > 0 && this.stepIndex - 1) || 0;
this.stepService.setCurrentIndex(newStep);
this.close(newStep, 'prev');
}
closeAll() {
try {
localStorage.setItem(`devui_guide_${this.pageName}`, '0');
}
catch (error) {
console.error(error);
}
this.close(this.stepService.getCurrentStep(), 'close');
}
close(step, type) { }
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideComponent, deps: [{ token: StepsGuideService }, { token: i0.Renderer2 }, { token: i2.PositionService }, { token: i0.ElementRef }, { token: i3.I18nService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StepsGuideComponent, selector: "ng-component", host: { properties: { "class": "this.class", "style.display": "this.display" } }, ngImport: i0, template: "<div class=\"devui-shining-dot\"></div>\n<div class=\"devui-shining-plus\"></div>\n<div class=\"devui-arrow\"></div>\n<div class=\"devui-guide-container\">\n <p class=\"devui-title\">{{ title }}</p>\n <div class=\"icon icon-close\" (click)=\"closeAll()\"></div>\n <ng-template [ngTemplateOutlet]=\"content | dIsTemplatePipe : plainText\"></ng-template>\n <ng-template #plainText>\n <div class=\"devui-content\" [innerHTML]=\"content | safe : 'html'\"></div>\n </ng-template>\n <div class=\"devui-ctrl\">\n <div *ngIf=\"dots.length > 1 && !extraConfig?.hideStepNav\" class=\"devui-dots\">\n <em *ngFor=\"let dot of dots; index as i\" class=\"icon icon-dot-status {{ i === stepIndex ? 'devui-active' : '' }}\"></em>\n </div>\n <div class=\"devui-guide-btn\">\n <div *ngIf=\"stepIndex > 0 && !extraConfig?.hidePreStep\" class=\"devui-prev-step\" (click)=\"prev()\">{{ i18nCommonText.previous }}</div>\n <div *ngIf=\"stepIndex + 1 < stepsCount\" (click)=\"next()\">{{ i18nCommonText.next }}</div>\n <div *ngIf=\"stepIndex === stepsCount - 1\" (click)=\"closeAll()\">{{ i18nCommonText.finish }}</div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.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.devui-step-item{width:400px;min-height:160px;background:var(--devui-brand, #0a59f7);box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) var(--devui-light-shadow, rgba(0, 0, 0, .08));border-radius:var(--devui-border-radius-feedback, 4px);font-size:var(--devui-font-size, 12px);color:var(--devui-light-text, #ffffff);padding:20px;position:absolute}:host.devui-step-item .devui-title{font-size:var(--devui-font-size-page-title, 16px);opacity:1;margin:0 0 20px;padding:0}:host.devui-step-item>.devui-arrow,:host.devui-step-item>.devui-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}:host.devui-step-item>.devui-arrow{border-width:8px}:host.devui-step-item.left>.devui-arrow{top:23px;right:-6px;margin-top:-3px;border-right-width:0;transform:rotate(-135deg);border-left-color:var(--devui-brand, #0a59f7)}:host.devui-step-item.top>.devui-arrow,:host.devui-step-item.top-left>.devui-arrow,:host.devui-step-item.top-right>.devui-arrow{bottom:-6px;border-bottom-width:0;border-top-color:var(--devui-brand, #0a59f7);transform:rotate(135deg)}:host.devui-step-item.top>.devui-arrow{left:calc(50% - 4px)}:host.devui-step-item.top-left>.devui-arrow{left:23px}:host.devui-step-item.top-right>.devui-arrow{right:23px;transform:rotate(-135deg)}:host.devui-step-item.right>.devui-arrow{top:23px;left:-6px;margin-top:-3px;border-left-width:0;transform:rotate(135deg);border-right-color:var(--devui-brand, #0a59f7)}:host.devui-step-item.bottom>.devui-arrow,:host.devui-step-item.bottom-left>.devui-arrow,:host.devui-step-item.bottom-right>.devui-arrow{top:-6px;margin-left:3px;border-top-width:0;border-bottom-color:var(--devui-brand, #0a59f7)}:host.devui-step-item.bottom>.devui-arrow{left:calc(50% - 4px);transform:rotate(-135deg)}:host.devui-step-item.bottom-right>.devui-arrow{right:23px;transform:rotate(135deg)}:host.devui-step-item.bottom-left>.devui-arrow{left:23px;transform:rotate(-135deg)}:host.devui-step-item>.devui-shining-dot,:host.devui-step-item .devui-shining-plus{position:absolute;background:var(--devui-brand, #0a59f7);width:6px;height:6px;border-radius:var(--devui-border-radius-feedback, 4px)}:host.devui-step-item.left>.devui-shining-dot,:host.devui-step-item.left>.devui-shining-plus{top:21px;right:-30px}:host.devui-step-item.right>.devui-shining-dot,:host.devui-step-item.right>.devui-shining-plus{top:21px;left:-30px}:host.devui-step-item.top>.devui-shining-dot,:host.devui-step-item.top>.devui-shining-plus{left:calc(50% - 3px);bottom:-30px}:host.devui-step-item.top-left>.devui-shining-dot,:host.devui-step-item.top-left>.devui-shining-plus{left:21px;bottom:-30px}:host.devui-step-item.top-right>.devui-shining-dot,:host.devui-step-item.top-right>.devui-shining-plus{right:21px;bottom:-30px}:host.devui-step-item.bottom>.devui-shining-dot,:host.devui-step-item.bottom>.devui-shining-plus{left:calc(50% - 3px);top:-30px}:host.devui-step-item.bottom-right>.devui-shining-dot,:host.devui-step-item.bottom-right>.devui-shining-plus{top:-30px;right:21px}:host.devui-step-item.bottom-left>.devui-shining-dot,:host.devui-step-item.bottom-left>.devui-shining-plus{top:-30px;left:21px}:host.devui-step-item .devui-shining-plus{animation:devui-glow 2s 0s infinite}:host.devui-step-item .devui-guide-container{position:relative}:host.devui-step-item .devui-guide-container>.icon-close{position:absolute;top:0;right:0;cursor:pointer}:host.devui-step-item .devui-guide-container .devui-ctrl{display:flex;flex-wrap:wrap}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-dots{color:var(--devui-light-text, #ffffff);position:relative;top:25px;font-size:var(--devui-font-size, 12px);height:30px}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-dots>em{opacity:.2;margin:0 5px 0 2px}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-dots>em.devui-active{opacity:1}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-guide-btn{display:flex;flex-flow:row nowrap;flex-grow:1;justify-content:flex-end;padding:20px 0 0;white-space:nowrap}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-guide-btn>div{color:var(--devui-light-text, #ffffff);background:#ffffff1a;border-radius:var(--devui-border-radius, 2px);padding:5px 15px;cursor:pointer;margin-left:10px}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-guide-btn>div.devui-prev-step{background:none;border:solid 1px rgba(255,255,255,.1)}@keyframes devui-glow{0%{transform:scale(1);opacity:.5}25%{transform:scale(2);opacity:.3}50%{transform:scale(3);opacity:.1}75%{transform:scale(2);opacity:.3}to{transform:scale(1);opacity:.5}}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i5.IsTemplatePipe, name: "dIsTemplatePipe" }, { kind: "pipe", type: i5.SafePipe, name: "safe" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideComponent, decorators: [{
type: Component,
args: [{ preserveWhitespaces: false, template: "<div class=\"devui-shining-dot\"></div>\n<div class=\"devui-shining-plus\"></div>\n<div class=\"devui-arrow\"></div>\n<div class=\"devui-guide-container\">\n <p class=\"devui-title\">{{ title }}</p>\n <div class=\"icon icon-close\" (click)=\"closeAll()\"></div>\n <ng-template [ngTemplateOutlet]=\"content | dIsTemplatePipe : plainText\"></ng-template>\n <ng-template #plainText>\n <div class=\"devui-content\" [innerHTML]=\"content | safe : 'html'\"></div>\n </ng-template>\n <div class=\"devui-ctrl\">\n <div *ngIf=\"dots.length > 1 && !extraConfig?.hideStepNav\" class=\"devui-dots\">\n <em *ngFor=\"let dot of dots; index as i\" class=\"icon icon-dot-status {{ i === stepIndex ? 'devui-active' : '' }}\"></em>\n </div>\n <div class=\"devui-guide-btn\">\n <div *ngIf=\"stepIndex > 0 && !extraConfig?.hidePreStep\" class=\"devui-prev-step\" (click)=\"prev()\">{{ i18nCommonText.previous }}</div>\n <div *ngIf=\"stepIndex + 1 < stepsCount\" (click)=\"next()\">{{ i18nCommonText.next }}</div>\n <div *ngIf=\"stepIndex === stepsCount - 1\" (click)=\"closeAll()\">{{ i18nCommonText.finish }}</div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.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.devui-step-item{width:400px;min-height:160px;background:var(--devui-brand, #0a59f7);box-shadow:var(--devui-shadow-length-feedback-overlay, 0 8px 24px 0) var(--devui-light-shadow, rgba(0, 0, 0, .08));border-radius:var(--devui-border-radius-feedback, 4px);font-size:var(--devui-font-size, 12px);color:var(--devui-light-text, #ffffff);padding:20px;position:absolute}:host.devui-step-item .devui-title{font-size:var(--devui-font-size-page-title, 16px);opacity:1;margin:0 0 20px;padding:0}:host.devui-step-item>.devui-arrow,:host.devui-step-item>.devui-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}:host.devui-step-item>.devui-arrow{border-width:8px}:host.devui-step-item.left>.devui-arrow{top:23px;right:-6px;margin-top:-3px;border-right-width:0;transform:rotate(-135deg);border-left-color:var(--devui-brand, #0a59f7)}:host.devui-step-item.top>.devui-arrow,:host.devui-step-item.top-left>.devui-arrow,:host.devui-step-item.top-right>.devui-arrow{bottom:-6px;border-bottom-width:0;border-top-color:var(--devui-brand, #0a59f7);transform:rotate(135deg)}:host.devui-step-item.top>.devui-arrow{left:calc(50% - 4px)}:host.devui-step-item.top-left>.devui-arrow{left:23px}:host.devui-step-item.top-right>.devui-arrow{right:23px;transform:rotate(-135deg)}:host.devui-step-item.right>.devui-arrow{top:23px;left:-6px;margin-top:-3px;border-left-width:0;transform:rotate(135deg);border-right-color:var(--devui-brand, #0a59f7)}:host.devui-step-item.bottom>.devui-arrow,:host.devui-step-item.bottom-left>.devui-arrow,:host.devui-step-item.bottom-right>.devui-arrow{top:-6px;margin-left:3px;border-top-width:0;border-bottom-color:var(--devui-brand, #0a59f7)}:host.devui-step-item.bottom>.devui-arrow{left:calc(50% - 4px);transform:rotate(-135deg)}:host.devui-step-item.bottom-right>.devui-arrow{right:23px;transform:rotate(135deg)}:host.devui-step-item.bottom-left>.devui-arrow{left:23px;transform:rotate(-135deg)}:host.devui-step-item>.devui-shining-dot,:host.devui-step-item .devui-shining-plus{position:absolute;background:var(--devui-brand, #0a59f7);width:6px;height:6px;border-radius:var(--devui-border-radius-feedback, 4px)}:host.devui-step-item.left>.devui-shining-dot,:host.devui-step-item.left>.devui-shining-plus{top:21px;right:-30px}:host.devui-step-item.right>.devui-shining-dot,:host.devui-step-item.right>.devui-shining-plus{top:21px;left:-30px}:host.devui-step-item.top>.devui-shining-dot,:host.devui-step-item.top>.devui-shining-plus{left:calc(50% - 3px);bottom:-30px}:host.devui-step-item.top-left>.devui-shining-dot,:host.devui-step-item.top-left>.devui-shining-plus{left:21px;bottom:-30px}:host.devui-step-item.top-right>.devui-shining-dot,:host.devui-step-item.top-right>.devui-shining-plus{right:21px;bottom:-30px}:host.devui-step-item.bottom>.devui-shining-dot,:host.devui-step-item.bottom>.devui-shining-plus{left:calc(50% - 3px);top:-30px}:host.devui-step-item.bottom-right>.devui-shining-dot,:host.devui-step-item.bottom-right>.devui-shining-plus{top:-30px;right:21px}:host.devui-step-item.bottom-left>.devui-shining-dot,:host.devui-step-item.bottom-left>.devui-shining-plus{top:-30px;left:21px}:host.devui-step-item .devui-shining-plus{animation:devui-glow 2s 0s infinite}:host.devui-step-item .devui-guide-container{position:relative}:host.devui-step-item .devui-guide-container>.icon-close{position:absolute;top:0;right:0;cursor:pointer}:host.devui-step-item .devui-guide-container .devui-ctrl{display:flex;flex-wrap:wrap}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-dots{color:var(--devui-light-text, #ffffff);position:relative;top:25px;font-size:var(--devui-font-size, 12px);height:30px}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-dots>em{opacity:.2;margin:0 5px 0 2px}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-dots>em.devui-active{opacity:1}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-guide-btn{display:flex;flex-flow:row nowrap;flex-grow:1;justify-content:flex-end;padding:20px 0 0;white-space:nowrap}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-guide-btn>div{color:var(--devui-light-text, #ffffff);background:#ffffff1a;border-radius:var(--devui-border-radius, 2px);padding:5px 15px;cursor:pointer;margin-left:10px}:host.devui-step-item .devui-guide-container .devui-ctrl .devui-guide-btn>div.devui-prev-step{background:none;border:solid 1px rgba(255,255,255,.1)}@keyframes devui-glow{0%{transform:scale(1);opacity:.5}25%{transform:scale(2);opacity:.3}50%{transform:scale(3);opacity:.1}75%{transform:scale(2);opacity:.3}to{transform:scale(1);opacity:.5}}\n"] }]
}], ctorParameters: () => [{ type: StepsGuideService }, { type: i0.Renderer2 }, { type: i2.PositionService }, { type: i0.ElementRef }, { type: i3.I18nService }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { class: [{
type: HostBinding,
args: ['class']
}], display: [{
type: HostBinding,
args: ['style.display']
}] } });
class StepsGuideDirective {
set dStepsGuidePosition(pos) {
this._dStepsGuidePosition = pos;
}
get dStepsGuidePosition() {
return this._dStepsGuidePosition || 'top';
}
/**
* @deprecated Use dStepsGuidePosition to replace.
*/
set position(pos) {
if (!this._dStepsGuidePosition) {
this.dStepsGuidePosition = pos;
}
}
// 允许用户指定一个dom反馈页面变化,通过MutationObserver监听该dom所属节点树变化触发resize事件使引导弹窗自动修正位置
set observerDom(dom) {
if (dom) {
this._observerDom = dom;
// 创建监听实例,并限制回调方法在500ms内只响应一次,避免多次响应dom变化造成性能负担
this.observer = new MutationObserver(throttle(this.mutationCallBack, this.MUTATION_OBSERVER_TIME, { 'leading': false, 'trailing': true }));
this.observer.observe(this._observerDom, this.MUTATION_OBSERVER_CONFIG);
}
else {
this.destroyMutationObserver(true);
}
}
constructor(stepService, elm, componentFactoryResolver, overlayContainerRef, doc) {
this.stepService = stepService;
this.elm = elm;
this.componentFactoryResolver = componentFactoryResolver;
this.overlayContainerRef = overlayContainerRef;
this.doc = doc;
this.steps = [];
// 可选,用于修正引导位置
this.leftFix = 0;
this.topFix = 0;
this.zIndex = 1100;
// 是否自动滚动页面至目标
this.scrollToTargetSwitch = true;
// 点击引导操作触发,返回当前步骤和当前操作,比如上一步、下一步、关闭
this.operateChange = new EventEmitter();
this.sub = new Subscription();
// 监听dom变化的设置,监听属性变化和dom所属节点树变化
this.MUTATION_OBSERVER_CONFIG = { attributes: true, subtree: true };
this.MUTATION_OBSERVER_TIME = 500;
// 监听dom变化的回调方法,即dom发生变化时触发resize事件
this.mutationCallBack = () => {
if (typeof window === 'undefined') {
return;
}
const resizeEvt = this.document.createEvent('Event');
resizeEvt.initEvent('resize', true, true);
window.dispatchEvent(resizeEvt);
};
this.document = this.doc;
}
ngOnInit() {
// 监听当前索引变化,决定显示步骤
this.sub.add(this.stepService.currentIndex.subscribe(index => {
this.canChange(index).then((change) => {
if (!change) {
return;
}
});
// 防止服务中的步骤被置空或默认为空
const serviceSteps = this.stepService.getSteps() || [];
this.steps = serviceSteps.length > 0 ? serviceSteps : this.steps;
const state = localStorage.getItem(`devui_guide_${this.pageName}`) || '1';
this.toggle = Number(state);
this.currentIndex = index;
const currentStep = this.steps.length > 0 && this.steps[this.currentIndex];
// 当前步骤内容存在且未被屏蔽显示且为当前索引时插入操作指引弹窗
if (currentStep && this.toggle && this.stepIndex === this.currentIndex) {
const targetDom = this.targetElement || this.elm.nativeElement;
if (this.scrollToTargetSwitch) {
targetDom.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
}
// 如果该步骤设置了监听dom和监听实例,重启监听
if (this._observerDom && this.observer) {
this.observer.disconnect();
this.observer.observe(this._observerDom, this.MUTATION_OBSERVER_CONFIG);
}
setTimeout(() => {
this.insert({
triggerElement: targetDom,
scrollElement: this.scrollElement,
pageName: this.pageName,
title: currentStep.title,
content: currentStep.content,
stepsCount: this.steps.length,
stepIndex: this.stepIndex,
position: this.dStepsGuidePosition,
leftFix: this.leftFix,
topFix: this.topFix,
zIndex: this.zIndex,
});
});
}
}));
// 监听切换显示和隐藏
this.sub.add(this.stepService.showGuideObs.subscribe(visible => {
if (visible) {
const currentIndex = this.stepService.getCurrentStep() || 0;
localStorage.removeItem(`devui_guide_${this.pageName}`);
this.stepService.setCurrentIndex(currentIndex);
}
else {
try {
localStorage.setItem(`devui_guide_${this.pageName}`, '0');
}
catch (error) {
console.error(error);
}
this.destroyView();
}
}));
}
ngOnDestroy() {
this.sub.unsubscribe();
this.destroyView();
}
destroyView() {
if (this.stepRef) {
this.stepRef.hostView.destroy();
}
this.destroyMutationObserver();
}
insert(option) {
const hasGuide = this.document.querySelector('body>.devui-step-item');
if (!hasGuide) {
this.stepRef = this.overlayContainerRef.createComponent(this.componentFactoryResolver.resolveComponentFactory(StepsGuideComponent));
Object.assign(this.stepRef.instance, option, { extraConfig: this.extraConfig });
this.stepRef.instance.close = (step, type) => {
this.operateChange.emit({ clickType: type, currentIndex: step });
this.destroyView();
};
}
}
// 断开监听, 清空监听dom和实例
destroyMutationObserver(destroyAll) {
if (this.observer) {
this.observer.disconnect();
}
if (destroyAll) {
this._observerDom = undefined;
this.observer = undefined;
}
}
canChange(index) {
let changeResult = Promise.resolve(true);
const currentIndex = this.currentIndex >= 0 ? this.currentIndex : this.stepIndex;
if (currentIndex === index && this.beforeChange) {
const result = this.beforeChange(currentIndex, index);
if (typeof result !== 'undefined') {
if (result.then) {
changeResult = result;
}
else if (result.subscribe) {
changeResult = result.toPromise();
}
else {
changeResult = Promise.resolve(result);
}
}
}
return changeResult;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideDirective, deps: [{ token: StepsGuideService }, { token: i0.ElementRef }, { token: i0.ComponentFactoryResolver }, { token: i2$1.OverlayContainerRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: StepsGuideDirective, selector: "[dStepsGuide]", inputs: { pageName: "pageName", steps: "steps", stepIndex: "stepIndex", dStepsGuidePosition: "dStepsGuidePosition", position: "position", leftFix: "leftFix", topFix: "topFix", zIndex: "zIndex", targetElement: "targetElement", scrollElement: "scrollElement", scrollToTargetSwitch: "scrollToTargetSwitch", extraConfig: "extraConfig", observerDom: "observerDom", beforeChange: "beforeChange" }, outputs: { operateChange: "operateChange" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideDirective, decorators: [{
type: Directive,
args: [{
selector: '[dStepsGuide]',
}]
}], ctorParameters: () => [{ type: StepsGuideService }, { type: i0.ElementRef }, { type: i0.ComponentFactoryResolver }, { type: i2$1.OverlayContainerRef }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { pageName: [{
type: Input
}], steps: [{
type: Input
}], stepIndex: [{
type: Input
}], dStepsGuidePosition: [{
type: Input
}], position: [{
type: Input
}], leftFix: [{
type: Input
}], topFix: [{
type: Input
}], zIndex: [{
type: Input
}], targetElement: [{
type: Input
}], scrollElement: [{
type: Input
}], scrollToTargetSwitch: [{
type: Input
}], extraConfig: [{
type: Input
}], observerDom: [{
type: Input
}], beforeChange: [{
type: Input
}], operateChange: [{
type: Output
}] } });
class StepsGuideModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideModule, declarations: [StepsGuideComponent, StepsGuideDirective], imports: [CommonModule, IsTemplateModule, SafePipeModule, PositioningModule], exports: [StepsGuideDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideModule, providers: [OverlayContainerRef, StepsGuideService], imports: [CommonModule, IsTemplateModule, SafePipeModule, PositioningModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepsGuideModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule, IsTemplateModule, SafePipeModule, PositioningModule],
declarations: [StepsGuideComponent, StepsGuideDirective],
exports: [StepsGuideDirective],
providers: [OverlayContainerRef, StepsGuideService],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { StepsGuideComponent, StepsGuideDirective, StepsGuideModule, StepsGuideService };
//# sourceMappingURL=ng-devui-steps-guide.mjs.map