Я создал директиву обертки над Popper. js, которая выглядит следующим образом:
import { Directive, ElementRef, Input, OnDestroy, OnInit, Renderer2 } from '@angular/core';
import Popper, { Placement, PopperOptions } from "popper.js";
import { Subject, merge, fromEvent } from 'rxjs';
import { filter, pluck, takeUntil } from 'rxjs/operators';
@Directive({
selector: "[espTooltip]"
})
export class TooltipDirective implements OnInit, OnDestroy {
// The hint to display
@Input() target: HTMLElement;
// Its positioning (check docs for available options)
@Input() placement?: Placement;
// Optional hint target if you desire using other element than specified one
@Input() appPopper?: HTMLElement;
@Input() text = '';
// The popper instance
private popper: Popper;
private readonly defaultConfig: PopperOptions = {
placement: "bottom",
removeOnDestroy: true,
modifiers: {
arrow: {
element: ".popper__arrow"
}
},
eventsEnabled: false
};
private readonly destroy$ = new Subject<void>();
constructor(
private readonly el: ElementRef,
private readonly renderer: Renderer2
) { }
ngOnInit(): void {
// An element to position the hint relative to
const reference = this.appPopper ? this.appPopper : this.el.nativeElement;
this.popper = new Popper(reference, this.target, {
...this.defaultConfig,
placement: this.placement || this.defaultConfig.placement
});
this.renderer.setStyle(this.target, "display", "none");
merge(
fromEvent(reference, "mouseenter"),
fromEvent(reference, "mouseleave")
)
.pipe(
filter(() => this.popper != null),
pluck("type"),
takeUntil(this.destroy$)
)
.subscribe((e: any) => this.mouseHoverHandler(e));
}
ngOnDestroy(): void {
if (!this.popper) {
return;
}
this.popper.destroy();
this.destroy$.next();
this.destroy$.complete();
}
private mouseHoverHandler(e: string): void {
if (e === "mouseenter") {
this.renderer.removeStyle(this.target, "display");
this.popper.enableEventListeners();
this.popper.scheduleUpdate();
} else {
this.renderer.setStyle(this.target, "display", "none");
this.popper.disableEventListeners();
}
}
}
Затем директива использовалась в компоненте, и после этого теста компонента была завершена с этой ошибкой:
TypeError: popper_js_1.default is not a constructor
41 | const reference = this.appPopper ? this.appPopper : this.el.nat
iveElement;
42 |
> 43 | this.popper = new Popper(reference, this.target, {
| ^
44 | ...this.defaultConfig,
45 | placement: this.placement || this.defaultConfig.placement
46 | });
Тестовая настройка:
@Directive({
selector: '[espTooltip]'
})
export class MockTooltipDirective {
@Input() target: HTMLElement;
// Its positioning (check docs for available options)
@Input() placement?: Popper.Placement;
// Optional hint target if you desire using other element than specified one
@Input() appPopper?: HTMLElement;
@Input() text = '';
private popper: any;
ngOnInit(): void {
// An element to position the hint relative to
this.popper = new Popper({clientHeight: 0, clientWidth: 0, getBoundingClientRect: jest.fn()}, null, {});
}
}
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
SharedModule
],
declarations: [
MockTooltipDirective,
PanelComponent,
ActiveJobsListComponent
],
})
.compileComponents();
}));
Что я тут не так делаю?