overlay.directive.mjs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { Directive, EventEmitter, HostListener, Input, Output, } from '@angular/core';
  2. import { TemplatePortal } from '@angular/cdk/portal';
  3. import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
  4. import { debounceTime } from 'rxjs';
  5. import * as i0 from "@angular/core";
  6. import * as i1 from "@angular/cdk/overlay";
  7. export class OverlayDirective {
  8. constructor(overlay, elementRef, viewContainerRef, destroyRef) {
  9. this.overlay = overlay;
  10. this.elementRef = elementRef;
  11. this.viewContainerRef = viewContainerRef;
  12. this.destroyRef = destroyRef;
  13. this.verticalPositions = {
  14. bottomStart: {
  15. originX: 'start',
  16. originY: 'bottom',
  17. overlayX: 'start',
  18. overlayY: 'top',
  19. },
  20. topStart: {
  21. originX: 'start',
  22. originY: 'top',
  23. overlayX: 'start',
  24. overlayY: 'bottom',
  25. },
  26. bottomEnd: {
  27. originX: 'end',
  28. originY: 'bottom',
  29. overlayX: 'end',
  30. overlayY: 'top',
  31. },
  32. topEnd: {
  33. originX: 'end',
  34. originY: 'top',
  35. overlayX: 'end',
  36. overlayY: 'bottom',
  37. },
  38. };
  39. this.horizontalPositions = {
  40. bottomStart: {
  41. originX: 'end',
  42. originY: 'bottom',
  43. overlayX: 'start',
  44. overlayY: 'bottom',
  45. offsetY: 7,
  46. },
  47. topStart: {
  48. originX: 'start',
  49. originY: 'bottom',
  50. overlayX: 'end',
  51. overlayY: 'bottom',
  52. },
  53. };
  54. this.overlayRef = null;
  55. this.position = 'horizontal';
  56. this.opened = new EventEmitter();
  57. this.closed = new EventEmitter();
  58. }
  59. show() {
  60. this.openDropdown();
  61. this.opened.emit();
  62. }
  63. openDropdown() {
  64. if (!this.overlayRef) {
  65. this.overlayRef = this.overlay.create({
  66. positionStrategy: this.getOverlayPosition(),
  67. });
  68. this.overlayRef
  69. .outsidePointerEvents()
  70. .pipe(takeUntilDestroyed(this.destroyRef), debounceTime(100))
  71. .subscribe(() => {
  72. this.closeDropdown();
  73. this.closed.emit();
  74. });
  75. }
  76. if (this.contentTemplate && !this.overlayRef.hasAttached()) {
  77. const portal = new TemplatePortal(this.contentTemplate, this.viewContainerRef);
  78. this.overlayRef.attach(portal);
  79. }
  80. }
  81. closeDropdown() {
  82. if (this.overlayRef?.hasAttached()) {
  83. this.overlayRef.detach();
  84. }
  85. }
  86. getOverlayPosition() {
  87. const positions = this.position === 'horizontal' ? this.horizontalPositions : this.verticalPositions;
  88. return this.overlay
  89. .position()
  90. .flexibleConnectedTo(this.elementRef)
  91. .withPositions(Object.keys(positions).map(positionKey => positions[positionKey]));
  92. }
  93. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: OverlayDirective, deps: [{ token: i1.Overlay }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Directive }); }
  94. static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.5", type: OverlayDirective, isStandalone: true, selector: "[ctOverlay]", inputs: { contentTemplate: ["ctOverlay", "contentTemplate"], position: ["ctOverlayPosition", "position"] }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "click": "show()", "touchstart": "show()" } }, ngImport: i0 }); }
  95. }
  96. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: OverlayDirective, decorators: [{
  97. type: Directive,
  98. args: [{
  99. selector: '[ctOverlay]',
  100. standalone: true,
  101. }]
  102. }], ctorParameters: () => [{ type: i1.Overlay }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.DestroyRef }], propDecorators: { contentTemplate: [{
  103. type: Input,
  104. args: ['ctOverlay']
  105. }], position: [{
  106. type: Input,
  107. args: ['ctOverlayPosition']
  108. }], opened: [{
  109. type: Output
  110. }], closed: [{
  111. type: Output
  112. }], show: [{
  113. type: HostListener,
  114. args: ['click']
  115. }, {
  116. type: HostListener,
  117. args: ['touchstart']
  118. }] } });
  119. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jaXJjbGV0b25lL3NyYy9saWIvZGlyZWN0aXZlcy9vdmVybGF5LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUVULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sR0FHUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFckQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQzs7O0FBTXBDLE1BQU0sT0FBTyxnQkFBZ0I7SUFnRDNCLFlBQ1UsT0FBZ0IsRUFDaEIsVUFBc0IsRUFDdEIsZ0JBQWtDLEVBQ3pCLFVBQXNCO1FBSC9CLFlBQU8sR0FBUCxPQUFPLENBQVM7UUFDaEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ3pCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFuRGpDLHNCQUFpQixHQUF5QztZQUNoRSxXQUFXLEVBQUU7Z0JBQ1gsT0FBTyxFQUFFLE9BQU87Z0JBQ2hCLE9BQU8sRUFBRSxRQUFRO2dCQUNqQixRQUFRLEVBQUUsT0FBTztnQkFDakIsUUFBUSxFQUFFLEtBQUs7YUFDaEI7WUFDRCxRQUFRLEVBQUU7Z0JBQ1IsT0FBTyxFQUFFLE9BQU87Z0JBQ2hCLE9BQU8sRUFBRSxLQUFLO2dCQUNkLFFBQVEsRUFBRSxPQUFPO2dCQUNqQixRQUFRLEVBQUUsUUFBUTthQUNuQjtZQUNELFNBQVMsRUFBRTtnQkFDVCxPQUFPLEVBQUUsS0FBSztnQkFDZCxPQUFPLEVBQUUsUUFBUTtnQkFDakIsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsUUFBUSxFQUFF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QkFDdkIsVUFBVSxFQUFFLElBQUk7aUJBQ2pCOzZKQTRDcUIsZUFBZTtzQkFBbEMsS0FBSzt1QkFBQyxXQUFXO2dCQUNVLFFBQVE7c0JBQW5DLEtBQUs7dUJBQUMsbUJBQW1CO2dCQUNoQixNQUFNO3NCQUFmLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQVdQLElBQUk7c0JBRkgsWUFBWTt1QkFBQyxPQUFPOztzQkFDcEIsWUFBWTt1QkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRGVzdHJveVJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDb250YWluZXJSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT3ZlcmxheSwgT3ZlcmxheVJlZiwgQ29ubmVjdGVkUG9zaXRpb24sIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IFRlbXBsYXRlUG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XG5pbXBvcnQgeyBDb21wb25lbnREaXNwb3NpdGlvbiB9IGZyb20gJy4uL21vZGVsL2NvbXBvbmVudHMvY29tcG9uZW50LWRpc3Bvc2l0aW9uLmVudW0nO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lIH0gZnJvbSAncnhqcyc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjdE92ZXJsYXldJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgT3ZlcmxheURpcmVjdGl2ZSB7XG4gIHByaXZhdGUgdmVydGljYWxQb3NpdGlvbnM6IHsgW2tleTogc3RyaW5nXTogQ29ubmVjdGVkUG9zaXRpb24gfSA9IHtcbiAgICBib3R0b21TdGFydDoge1xuICAgICAgb3JpZ2luWDogJ3N0YXJ0JyxcbiAgICAgIG9yaWdpblk6ICdib3R0b20nLFxuICAgICAgb3ZlcmxheVg6ICdzdGFydCcsXG4gICAgICBvdmVybGF5WTogJ3RvcCcsXG4gICAgfSxcbiAgICB0b3BTdGFydDoge1xuICAgICAgb3JpZ2luWDogJ3N0YXJ0JyxcbiAgICAgIG9yaWdpblk6ICd0b3AnLFxuICAgICAgb3ZlcmxheVg6ICdzdGFydCcsXG4gICAgICBvdmVybGF5WTogJ2JvdHRvbScsXG4gICAgfSxcbiAgICBib3R0b21FbmQ6IHtcbiAgICAgIG9yaWdpblg6ICdlbmQnLFxuICAgICAgb3JpZ2luWTogJ2JvdHRvbScsXG4gICAgICBvdmVybGF5WDogJ2VuZCcsXG4gICAgICBvdmVybGF5WTogJ3RvcCcsXG4gICAgfSxcbiAgICB0b3BFbmQ6IHtcbiAgICAgIG9yaWdpblg6ICdlbmQnLFxuICAgICAgb3JpZ2luWTogJ3RvcCcsXG4gICAgICBvdmVybGF5WDogJ2VuZCcsXG4gICAgICBvdmVybGF5WTogJ2JvdHRvbScsXG4gICAgfSxcbiAgfTtcbiAgcHJpdmF0ZSBob3Jpem9udGFsUG9zaXRpb25zOiB7IFtrZXk6IHN0cmluZ106IENvbm5lY3RlZFBvc2l0aW9uIH0gPSB7XG4gICAgYm90dG9tU3RhcnQ6IHtcbiAgICAgIG9yaWdpblg6ICdlbmQnLFxuICAgICAgb3JpZ2luWTogJ2JvdHRvbScsXG4gICAgICBvdmVybGF5WDogJ3N0YXJ0JyxcbiAgICAgIG92ZXJsYXlZOiAnYm90dG9tJyxcbiAgICAgIG9mZnNldFk6IDcsXG4gICAgfSxcbiAgICB0b3BTdGFydDoge1xuICAgICAgb3JpZ2luWDogJ3N0YXJ0JyxcbiAgICAgIG9yaWdpblk6ICdib3R0b20nLFxuICAgICAgb3ZlcmxheVg6ICdlbmQnLFxuICAgICAgb3ZlcmxheVk6ICdib3R0b20nLFxuICAgIH0sXG4gIH07XG4gIHByaXZhdGUgb3ZlcmxheVJlZjogT3ZlcmxheVJlZiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoJ2N0T3ZlcmxheScpIGNvbnRlbnRUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBJbnB1dCgnY3RPdmVybGF5UG9zaXRpb24nKSBwb3NpdGlvbjogQ29tcG9uZW50RGlzcG9zaXRpb24gPSAnaG9yaXpvbnRhbCc7XG4gIEBPdXRwdXQoKSBvcGVuZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBjbG9zZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBvdmVybGF5OiBPdmVybGF5LFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXG4gICAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmOiBEZXN0cm95UmVmXG4gICkge31cblxuICBASG9zdExpc3RlbmVyKCdjbGljaycpXG4gIEBIb3N0TGlzdGVuZXIoJ3RvdWNoc3RhcnQnKVxuICBzaG93KCk6IHZvaWQge1xuICAgIHRoaXMub3BlbkRyb3Bkb3duKCk7XG4gICAgdGhpcy5vcGVuZWQuZW1pdCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBvcGVuRHJvcGRvd24oKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm92ZXJsYXlSZWYpIHtcbiAgICAgIHRoaXMub3ZlcmxheVJlZiA9IHRoaXMub3ZlcmxheS5jcmVhdGUoe1xuICAgICAgICBwb3NpdGlvblN0cmF0ZWd5OiB0aGlzLmdldE92ZXJsYXlQb3NpdGlvbigpLFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMub3ZlcmxheVJlZlxuICAgICAgICAub3V0c2lkZVBvaW50ZXJFdmVudHMoKVxuICAgICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSwgZGVib3VuY2VUaW1lKDEwMCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgICAgICAgIHRoaXMuY2xvc2VkLmVtaXQoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29udGVudFRlbXBsYXRlICYmICF0aGlzLm92ZXJsYXlSZWYuaGFzQXR0YWNoZWQoKSkge1xuICAgICAgY29uc3QgcG9ydGFsID0gbmV3IFRlbXBsYXRlUG9ydGFsKHRoaXMuY29udGVudFRlbXBsYXRlLCB0aGlzLnZpZXdDb250YWluZXJSZWYpO1xuICAgICAgdGhpcy5vdmVybGF5UmVmLmF0dGFjaChwb3J0YWwpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VEcm9wZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vdmVybGF5UmVmPy5oYXNBdHRhY2hlZCgpKSB7XG4gICAgICB0aGlzLm92ZXJsYXlSZWYuZGV0YWNoKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRPdmVybGF5UG9zaXRpb24oKTogRmxleGlibGVDb25uZWN0ZWRQb3NpdGlvblN0cmF0ZWd5IHtcbiAgICBjb25zdCBwb3NpdGlvbnMgPSB0aGlzLnBvc2l0aW9uID09PSAnaG9yaXpvbnRhbCcgPyB0aGlzLmhvcml6b250YWxQb3NpdGlvbnMgOiB0aGlzLnZlcnRpY2FsUG9zaXRpb25zO1xuICAgIHJldHVybiB0aGlzLm92ZXJsYXlcbiAgICAgIC5wb3NpdGlvbigpXG4gICAgICAuZmxleGlibGVDb25uZWN0ZWRUbyh0aGlzLmVsZW1lbnRSZWYpXG4gICAgICAud2l0aFBvc2l0aW9ucyhPYmplY3Qua2V5cyhwb3NpdGlvbnMpLm1hcChwb3NpdGlvbktleSA9PiBwb3NpdGlvbnNbcG9zaXRpb25LZXldKSk7XG4gIH1cbn1cbiJdfQ==