@ruc-lib/overlay 3.1.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -21
- package/esm2020/index.mjs +7 -0
- package/esm2020/lib/constants/positions.mjs +7 -0
- package/esm2020/lib/model/overlay.types.mjs +7 -0
- package/esm2020/lib/overlay-content/overlay-content.component.mjs +91 -0
- package/esm2020/lib/ruc-overlay-chart/ruc-overlay-chart.component.mjs +29 -0
- package/esm2020/lib/ruclib-overlay/ruclib-overlay.component.mjs +196 -0
- package/esm2020/lib/ruclib-overlay.module.mjs +48 -0
- package/esm2020/lib/service/overlay.service.mjs +33 -0
- package/esm2020/ruc-lib-overlay.mjs +5 -0
- package/fesm2015/ruc-lib-overlay.mjs +401 -0
- package/fesm2015/ruc-lib-overlay.mjs.map +1 -0
- package/fesm2020/ruc-lib-overlay.mjs +394 -0
- package/fesm2020/ruc-lib-overlay.mjs.map +1 -0
- package/index.d.ts +6 -115
- package/lib/constants/positions.d.ts +2 -0
- package/lib/model/overlay.types.d.ts +40 -0
- package/lib/overlay-content/overlay-content.component.d.ts +20 -0
- package/lib/ruc-overlay-chart/ruc-overlay-chart.component.d.ts +11 -0
- package/lib/ruclib-overlay/ruclib-overlay.component.d.ts +40 -0
- package/lib/ruclib-overlay.module.d.ts +15 -0
- package/lib/service/overlay.service.d.ts +16 -0
- package/package.json +21 -9
- package/fesm2022/ruc-lib-overlay.mjs +0 -355
- package/fesm2022/ruc-lib-overlay.mjs.map +0 -1
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
import * as i1$1 from '@angular/cdk/overlay';
|
|
2
|
-
import * as i0 from '@angular/core';
|
|
3
|
-
import { InjectionToken, Injectable, Input, ChangeDetectionStrategy, Component, EventEmitter, TemplateRef, HostBinding, Output, Inject, Injector, ElementRef, HostListener, ViewChild } from '@angular/core';
|
|
4
|
-
import { Subject, filter } from 'rxjs';
|
|
5
|
-
import { ComponentPortal } from '@angular/cdk/portal';
|
|
6
|
-
import * as i3 from '@angular/material/icon';
|
|
7
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
8
|
-
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
9
|
-
import * as i1 from '@angular/common';
|
|
10
|
-
import { CommonModule } from '@angular/common';
|
|
11
|
-
import Chart from 'chart.js/auto';
|
|
12
|
-
import * as i2 from '@angular/material/card';
|
|
13
|
-
import { MatCardModule } from '@angular/material/card';
|
|
14
|
-
import * as i4 from '@angular/material/button';
|
|
15
|
-
import { MatButtonModule, MatButton } from '@angular/material/button';
|
|
16
|
-
import { ESCAPE } from '@angular/cdk/keycodes';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* The Injection Token used to provide the PopoverControl object to the
|
|
20
|
-
* PopoverContentComponent. This is the correct, final version.
|
|
21
|
-
*/
|
|
22
|
-
const OVERLAY_CONTROL = new InjectionToken('OVERLAY_CONTROL');
|
|
23
|
-
|
|
24
|
-
class OverlayService {
|
|
25
|
-
constructor() {
|
|
26
|
-
this.popoverState = new Subject();
|
|
27
|
-
this.popoverState$ = this.popoverState.asObservable();
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Broadcasts a command to open a popover using the OverlayData structure.
|
|
31
|
-
*/
|
|
32
|
-
open(config, trigger) {
|
|
33
|
-
console.log(config, trigger);
|
|
34
|
-
// The service's responsibility is to bundle the config and trigger
|
|
35
|
-
// into a PopoverData object and send it.
|
|
36
|
-
this.popoverState.next({ config, trigger });
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Broadcasts a command to close any currently open service-controlled popover.
|
|
40
|
-
*/
|
|
41
|
-
close() {
|
|
42
|
-
this.popoverState.next(null);
|
|
43
|
-
}
|
|
44
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OverlayService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
45
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OverlayService, providedIn: 'root' }); }
|
|
46
|
-
}
|
|
47
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OverlayService, decorators: [{
|
|
48
|
-
type: Injectable,
|
|
49
|
-
args: [{
|
|
50
|
-
providedIn: 'root'
|
|
51
|
-
}]
|
|
52
|
-
}] });
|
|
53
|
-
|
|
54
|
-
class RucOverlayChartComponent {
|
|
55
|
-
constructor() {
|
|
56
|
-
this.index = 0;
|
|
57
|
-
}
|
|
58
|
-
ngAfterViewInit() {
|
|
59
|
-
if (this.chartConfig) {
|
|
60
|
-
this.chart = new Chart('canvas' + this.index, this.chartConfig);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
ngOnDestroy() {
|
|
64
|
-
this.chart?.destroy();
|
|
65
|
-
this.chart = null;
|
|
66
|
-
this.chartConfig = null;
|
|
67
|
-
}
|
|
68
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RucOverlayChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
69
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: RucOverlayChartComponent, isStandalone: true, selector: "uxp-ruc-overlay-chart", inputs: { index: "index", chartConfig: "chartConfig" }, ngImport: i0, template: "<div style=\"position: relative; height:220px;\">\r\n <canvas id=\"canvas{{index}}\">{{chart}}</canvas>\r\n</div>\r\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
70
|
-
}
|
|
71
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RucOverlayChartComponent, decorators: [{
|
|
72
|
-
type: Component,
|
|
73
|
-
args: [{ selector: 'uxp-ruc-overlay-chart', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div style=\"position: relative; height:220px;\">\r\n <canvas id=\"canvas{{index}}\">{{chart}}</canvas>\r\n</div>\r\n" }]
|
|
74
|
-
}], propDecorators: { index: [{
|
|
75
|
-
type: Input
|
|
76
|
-
}], chartConfig: [{
|
|
77
|
-
type: Input
|
|
78
|
-
}] } });
|
|
79
|
-
|
|
80
|
-
class OverlayContentComponent {
|
|
81
|
-
ngOnInit() {
|
|
82
|
-
if (this.control.config.tableData) {
|
|
83
|
-
this.getTableHeaders();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
get animationState() {
|
|
87
|
-
return this.control.config.animation === 'scale'
|
|
88
|
-
? 'enter-scale'
|
|
89
|
-
: 'enter-fade';
|
|
90
|
-
}
|
|
91
|
-
constructor(control) {
|
|
92
|
-
this.control = control;
|
|
93
|
-
this.actualPlacement = 'bottom';
|
|
94
|
-
this.tableHeaders = [];
|
|
95
|
-
this.arrowOffset = 0;
|
|
96
|
-
this.mouseEnterPopover = new EventEmitter();
|
|
97
|
-
this.mouseLeavePopover = new EventEmitter();
|
|
98
|
-
this.actualPlacement = this.control.config.placement || 'bottom';
|
|
99
|
-
}
|
|
100
|
-
// Helper to check if content is a TemplateRef
|
|
101
|
-
isTemplateRef(content) {
|
|
102
|
-
return content instanceof TemplateRef;
|
|
103
|
-
}
|
|
104
|
-
// Helper to get keys for the table header, robustly
|
|
105
|
-
getTableHeaders() {
|
|
106
|
-
const tempData = this.control.config.tableData;
|
|
107
|
-
if (!tempData || tempData.length === 0) {
|
|
108
|
-
this.tableHeaders = [];
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
// Assumes all objects in the array have the same shape
|
|
112
|
-
this.tableHeaders = Object.keys(tempData[0]);
|
|
113
|
-
}
|
|
114
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OverlayContentComponent, deps: [{ token: OVERLAY_CONTROL }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
115
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: OverlayContentComponent, isStandalone: true, selector: "uxp-overlay-content", inputs: { customTheme: "customTheme" }, outputs: { mouseEnterPopover: "mouseEnterPopover", mouseLeavePopover: "mouseLeavePopover" }, host: { properties: { "@popoverAnimation": "this.animationState" } }, ngImport: i0, template: "<mat-card class=\"popover-container\" class={{customTheme}} (click)=\"$event.stopPropagation()\">\r\n\r\n <div class=\"popover-arrow\"\r\n [attr.data-placement]=\"actualPlacement\"\r\n [style.left.px]=\"(actualPlacement.startsWith('top') || actualPlacement.startsWith('bottom')) ? arrowOffset : null\"\r\n [style.top.px]=\"(actualPlacement.startsWith('left') || actualPlacement.startsWith('right')) ? arrowOffset : null\">\r\n </div>\r\n <!-- Header with optional title and close button -->\r\n\r\n @if (\r\n control.config.overlayTitle ||\r\n control.config.showCloseButton ||\r\n control.config.closeIcon\r\n ) {\r\n <mat-card-header\r\n class=\"popover-header\"\r\n >\r\n @if (control.config.overlayTitle) {\r\n <mat-card-title class=\"popover-title\">{{ control.config.overlayTitle }}</mat-card-title>\r\n }\r\n @if (control.config.showCloseButton && control.config.closeIcon) {\r\n <button mat-icon-button class=\"close-btn\" (click)=\"control.close()\" color=\"primary\" aria-label=\"Close popover icon\">\r\n <mat-icon>{{ control.config.closeIcon }}</mat-icon>\r\n </button>\r\n }\r\n </mat-card-header>\r\n }\r\n\r\n\r\n <!-- Body with dynamic content -->\r\n <mat-card-content class=\"popover-body\">\r\n <!-- Case 1: Content is a simple string -->\r\n @if (\r\n !isTemplateRef(control.config.content) && !control.config.tableData\r\n ) {\r\n {{ control.config.content }}\r\n }\r\n\r\n <!-- Case 2: Content is a TemplateRef -->\r\n @if (isTemplateRef(control.config.content)) {\r\n <ng-container *ngTemplateOutlet=\"control.config.content\"></ng-container>\r\n }\r\n\r\n @if (control.config.chartConfig) {\r\n <uxp-ruc-overlay-chart [chartConfig]=\"control.config.chartConfig\"></uxp-ruc-overlay-chart>\r\n }\r\n\r\n <!-- Case 3: Content is table data -->\r\n @if (control.config.tableData?.length) {\r\n <table\r\n class=\"popover-table\"\r\n [class]=\"control.config.tableClass || 'basic-table'\"\r\n >\r\n <thead>\r\n <tr>\r\n @for (header of this.tableHeaders!; track header) {\r\n <th\r\n >\r\n {{ header }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of control.config.tableData; track row) {\r\n <tr>\r\n @for (header of this.tableHeaders!; track header) {\r\n <td\r\n >\r\n {{ row[header] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </mat-card-content>\r\n</mat-card>\r\n", styles: [":host{display:block}.popover-container{z-index:1080;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 5px 10px #0003;position:relative;max-width:300px}.popover-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;border-width:10px}.close-btn .mat-mdc-icon-button.mat-mdc-button-base{width:30px;height:30px;padding:2px}.popover-title{font-size:16px;font-weight:600}.mat-card-header.mat-mdc-card-header.popover-header .mat-mdc-card-header-text .mat-card-title.mat-mdc-card-title{font-size:16px}button.close-btn.mdc-icon-button.mat-mdc-icon-button.mat-mdc-button-base{width:30px;height:30px;padding:2px}.popover-arrow[data-placement^=bottom]{top:-10px;transform:translate(-50%);border-width:0 10px 10px 10px;border-bottom-color:#fff;filter:drop-shadow(0 -1px 1px rgba(0,0,0,.15))}.popover-arrow[data-placement^=top]{bottom:-10px;transform:translate(-50%);border-width:10px 10px 0 10px;border-top-color:#fff;filter:drop-shadow(0 1px 1px rgba(0,0,0,.15))}.popover-arrow[data-placement^=right]{left:-10px;transform:translateY(-50%);border-width:10px 10px 10px 0;border-right-color:#fff;filter:drop-shadow(-1px 0 1px rgba(0,0,0,.15))}.popover-arrow[data-placement^=left]{right:-10px;transform:translateY(-50%);border-width:10px 0 10px 10px;border-left-color:#fff;filter:drop-shadow(1px 0 1px rgba(0,0,0,.15))}.popover-header{display:flex;justify-content:space-between;align-items:center;padding:.5rem 1rem;margin:0;font-size:1rem;border-bottom:1px solid #dcdcdc;border-radius:5px 5px 0 0}.popover-header h3{margin:0;font-size:1rem}.popover-body{padding:9px 14px}.popover-table{width:100%;border-collapse:collapse;margin-top:5px}.popover-table th,.popover-table td{border:1px solid #ddd;padding:8px;text-align:left}.popover-table th{text-transform:capitalize}.striped-table{width:100%;border-collapse:collapse;font-size:.9em}.striped-table th,.striped-table td{border:1px solid #ddd;padding:8px;text-align:left}.striped-table thead th{font-weight:700}.striped-table tbody tr:nth-child(2n){background-color:#00000061}.basic-table{width:100%;border-collapse:collapse;font-size:.9em}.basic-table th,.basic-table td{border:1px solid #ddd;padding:8px;text-align:left}.basic-table thead th{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: RucOverlayChartComponent, selector: "uxp-ruc-overlay-chart", inputs: ["index", "chartConfig"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i2.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i2.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], animations: [
|
|
116
|
-
trigger('popoverAnimation', [
|
|
117
|
-
state('void', style({ transform: 'scale(0.9)', opacity: 0 })),
|
|
118
|
-
state('enter-scale', style({ transform: 'scale(1)', opacity: 1 })),
|
|
119
|
-
state('enter-fade', style({ opacity: 1 })),
|
|
120
|
-
transition('void => enter-scale', animate('150ms cubic-bezier(0, 0, 0.2, 1)')),
|
|
121
|
-
transition('void => enter-fade', [
|
|
122
|
-
style({ opacity: 0, transform: 'translateY(10px)' }),
|
|
123
|
-
animate('500ms', style({ opacity: 1, transform: 'translateY(0)' })),
|
|
124
|
-
]),
|
|
125
|
-
transition('* => void', [
|
|
126
|
-
animate('500ms', style({ opacity: 0, transform: 'translateY(10px)' })),
|
|
127
|
-
]),
|
|
128
|
-
]),
|
|
129
|
-
] }); }
|
|
130
|
-
}
|
|
131
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: OverlayContentComponent, decorators: [{
|
|
132
|
-
type: Component,
|
|
133
|
-
args: [{ selector: 'uxp-overlay-content', imports: [CommonModule, RucOverlayChartComponent, MatCardModule, MatIconModule, MatButtonModule], animations: [
|
|
134
|
-
trigger('popoverAnimation', [
|
|
135
|
-
state('void', style({ transform: 'scale(0.9)', opacity: 0 })),
|
|
136
|
-
state('enter-scale', style({ transform: 'scale(1)', opacity: 1 })),
|
|
137
|
-
state('enter-fade', style({ opacity: 1 })),
|
|
138
|
-
transition('void => enter-scale', animate('150ms cubic-bezier(0, 0, 0.2, 1)')),
|
|
139
|
-
transition('void => enter-fade', [
|
|
140
|
-
style({ opacity: 0, transform: 'translateY(10px)' }),
|
|
141
|
-
animate('500ms', style({ opacity: 1, transform: 'translateY(0)' })),
|
|
142
|
-
]),
|
|
143
|
-
transition('* => void', [
|
|
144
|
-
animate('500ms', style({ opacity: 0, transform: 'translateY(10px)' })),
|
|
145
|
-
]),
|
|
146
|
-
]),
|
|
147
|
-
], template: "<mat-card class=\"popover-container\" class={{customTheme}} (click)=\"$event.stopPropagation()\">\r\n\r\n <div class=\"popover-arrow\"\r\n [attr.data-placement]=\"actualPlacement\"\r\n [style.left.px]=\"(actualPlacement.startsWith('top') || actualPlacement.startsWith('bottom')) ? arrowOffset : null\"\r\n [style.top.px]=\"(actualPlacement.startsWith('left') || actualPlacement.startsWith('right')) ? arrowOffset : null\">\r\n </div>\r\n <!-- Header with optional title and close button -->\r\n\r\n @if (\r\n control.config.overlayTitle ||\r\n control.config.showCloseButton ||\r\n control.config.closeIcon\r\n ) {\r\n <mat-card-header\r\n class=\"popover-header\"\r\n >\r\n @if (control.config.overlayTitle) {\r\n <mat-card-title class=\"popover-title\">{{ control.config.overlayTitle }}</mat-card-title>\r\n }\r\n @if (control.config.showCloseButton && control.config.closeIcon) {\r\n <button mat-icon-button class=\"close-btn\" (click)=\"control.close()\" color=\"primary\" aria-label=\"Close popover icon\">\r\n <mat-icon>{{ control.config.closeIcon }}</mat-icon>\r\n </button>\r\n }\r\n </mat-card-header>\r\n }\r\n\r\n\r\n <!-- Body with dynamic content -->\r\n <mat-card-content class=\"popover-body\">\r\n <!-- Case 1: Content is a simple string -->\r\n @if (\r\n !isTemplateRef(control.config.content) && !control.config.tableData\r\n ) {\r\n {{ control.config.content }}\r\n }\r\n\r\n <!-- Case 2: Content is a TemplateRef -->\r\n @if (isTemplateRef(control.config.content)) {\r\n <ng-container *ngTemplateOutlet=\"control.config.content\"></ng-container>\r\n }\r\n\r\n @if (control.config.chartConfig) {\r\n <uxp-ruc-overlay-chart [chartConfig]=\"control.config.chartConfig\"></uxp-ruc-overlay-chart>\r\n }\r\n\r\n <!-- Case 3: Content is table data -->\r\n @if (control.config.tableData?.length) {\r\n <table\r\n class=\"popover-table\"\r\n [class]=\"control.config.tableClass || 'basic-table'\"\r\n >\r\n <thead>\r\n <tr>\r\n @for (header of this.tableHeaders!; track header) {\r\n <th\r\n >\r\n {{ header }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of control.config.tableData; track row) {\r\n <tr>\r\n @for (header of this.tableHeaders!; track header) {\r\n <td\r\n >\r\n {{ row[header] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </mat-card-content>\r\n</mat-card>\r\n", styles: [":host{display:block}.popover-container{z-index:1080;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 5px 10px #0003;position:relative;max-width:300px}.popover-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;border-width:10px}.close-btn .mat-mdc-icon-button.mat-mdc-button-base{width:30px;height:30px;padding:2px}.popover-title{font-size:16px;font-weight:600}.mat-card-header.mat-mdc-card-header.popover-header .mat-mdc-card-header-text .mat-card-title.mat-mdc-card-title{font-size:16px}button.close-btn.mdc-icon-button.mat-mdc-icon-button.mat-mdc-button-base{width:30px;height:30px;padding:2px}.popover-arrow[data-placement^=bottom]{top:-10px;transform:translate(-50%);border-width:0 10px 10px 10px;border-bottom-color:#fff;filter:drop-shadow(0 -1px 1px rgba(0,0,0,.15))}.popover-arrow[data-placement^=top]{bottom:-10px;transform:translate(-50%);border-width:10px 10px 0 10px;border-top-color:#fff;filter:drop-shadow(0 1px 1px rgba(0,0,0,.15))}.popover-arrow[data-placement^=right]{left:-10px;transform:translateY(-50%);border-width:10px 10px 10px 0;border-right-color:#fff;filter:drop-shadow(-1px 0 1px rgba(0,0,0,.15))}.popover-arrow[data-placement^=left]{right:-10px;transform:translateY(-50%);border-width:10px 0 10px 10px;border-left-color:#fff;filter:drop-shadow(1px 0 1px rgba(0,0,0,.15))}.popover-header{display:flex;justify-content:space-between;align-items:center;padding:.5rem 1rem;margin:0;font-size:1rem;border-bottom:1px solid #dcdcdc;border-radius:5px 5px 0 0}.popover-header h3{margin:0;font-size:1rem}.popover-body{padding:9px 14px}.popover-table{width:100%;border-collapse:collapse;margin-top:5px}.popover-table th,.popover-table td{border:1px solid #ddd;padding:8px;text-align:left}.popover-table th{text-transform:capitalize}.striped-table{width:100%;border-collapse:collapse;font-size:.9em}.striped-table th,.striped-table td{border:1px solid #ddd;padding:8px;text-align:left}.striped-table thead th{font-weight:700}.striped-table tbody tr:nth-child(2n){background-color:#00000061}.basic-table{width:100%;border-collapse:collapse;font-size:.9em}.basic-table th,.basic-table td{border:1px solid #ddd;padding:8px;text-align:left}.basic-table thead th{font-weight:700}\n"] }]
|
|
148
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
149
|
-
type: Inject,
|
|
150
|
-
args: [OVERLAY_CONTROL]
|
|
151
|
-
}] }], propDecorators: { customTheme: [{
|
|
152
|
-
type: Input
|
|
153
|
-
}], mouseEnterPopover: [{
|
|
154
|
-
type: Output
|
|
155
|
-
}], mouseLeavePopover: [{
|
|
156
|
-
type: Output
|
|
157
|
-
}], animationState: [{
|
|
158
|
-
type: HostBinding,
|
|
159
|
-
args: ['@popoverAnimation']
|
|
160
|
-
}] } });
|
|
161
|
-
|
|
162
|
-
const positions = [
|
|
163
|
-
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 10 },
|
|
164
|
-
{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -10 },
|
|
165
|
-
{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 10 },
|
|
166
|
-
{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -10 }
|
|
167
|
-
];
|
|
168
|
-
|
|
169
|
-
class RuclibOverlayComponent {
|
|
170
|
-
constructor(overlay, injector, overlayService) {
|
|
171
|
-
this.overlay = overlay;
|
|
172
|
-
this.injector = injector;
|
|
173
|
-
this.overlayService = overlayService;
|
|
174
|
-
this.rucInputData = {
|
|
175
|
-
content: 'Default content',
|
|
176
|
-
};
|
|
177
|
-
this.overlayRef = null;
|
|
178
|
-
}
|
|
179
|
-
ngOnInit() {
|
|
180
|
-
if (!this.buttonText) {
|
|
181
|
-
this.serviceSubscription = this.overlayService.popoverState$.subscribe((data) => {
|
|
182
|
-
if (data && !this.isOpen) {
|
|
183
|
-
this.show(data.trigger, data.config);
|
|
184
|
-
}
|
|
185
|
-
else if (!data) {
|
|
186
|
-
this.destroy();
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
ngOnDestroy() {
|
|
192
|
-
this.positionSubscription?.unsubscribe();
|
|
193
|
-
this.serviceSubscription?.unsubscribe();
|
|
194
|
-
this.destroy();
|
|
195
|
-
}
|
|
196
|
-
get isOpen() {
|
|
197
|
-
return !!this.overlayRef;
|
|
198
|
-
}
|
|
199
|
-
// --- Trigger Handlers for self-contained button ---
|
|
200
|
-
toggle() {
|
|
201
|
-
if (this.rucInputData.trigger !== 'hover') {
|
|
202
|
-
this.isOpen
|
|
203
|
-
? this.destroy()
|
|
204
|
-
: this.show(this.triggerButtonRef.nativeElement, this.rucInputData);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
handleMouseEnter() {
|
|
208
|
-
if (this.rucInputData.trigger === 'hover') {
|
|
209
|
-
if (this.closeTimeout)
|
|
210
|
-
clearTimeout(this.closeTimeout); // Clear any pending close command
|
|
211
|
-
this.show(this.triggerButtonRef.nativeElement, this.rucInputData);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
handleMouseLeave() {
|
|
215
|
-
if (this.rucInputData.trigger === 'hover') {
|
|
216
|
-
// Use the configurable closeDelay
|
|
217
|
-
const delay = this.rucInputData.closeDelay ?? 200;
|
|
218
|
-
this.closeTimeout = setTimeout(() => this.destroy(), delay);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
show(trigger, config) {
|
|
222
|
-
if (this.isOpen)
|
|
223
|
-
return;
|
|
224
|
-
const positionStrategy = this.createPositionStrategy(trigger, config.placement || 'bottom');
|
|
225
|
-
this.overlayRef = this.overlay.create({
|
|
226
|
-
positionStrategy,
|
|
227
|
-
hasBackdrop: config.trigger !== 'hover',
|
|
228
|
-
backdropClass: 'cdk-overlay-transparent-backdrop',
|
|
229
|
-
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
230
|
-
});
|
|
231
|
-
this.overlayRef.keydownEvents().pipe(filter(event => event.keyCode === ESCAPE)).subscribe(() => this.destroy());
|
|
232
|
-
const control = { config, close: this.destroy.bind(this) };
|
|
233
|
-
const injector = Injector.create({
|
|
234
|
-
parent: this.injector,
|
|
235
|
-
providers: [{ provide: OVERLAY_CONTROL, useValue: control }],
|
|
236
|
-
});
|
|
237
|
-
const portal = new ComponentPortal(OverlayContentComponent, null, injector);
|
|
238
|
-
const componentRef = this.overlayRef.attach(portal);
|
|
239
|
-
componentRef.instance.customTheme = this.customTheme;
|
|
240
|
-
// --- START: MODIFICATION FOR DYNAMIC ARROW ---
|
|
241
|
-
this.positionSubscription = positionStrategy.positionChanges.subscribe((change) => {
|
|
242
|
-
// 1. Get the new placement ('top', 'bottom', etc.)
|
|
243
|
-
const newPlacement = this.getPlacementFromPosition(change.connectionPair);
|
|
244
|
-
componentRef.instance.actualPlacement = newPlacement;
|
|
245
|
-
// 2. Calculate the arrow's offset
|
|
246
|
-
if (this.overlayRef) {
|
|
247
|
-
const triggerRect = trigger.getBoundingClientRect();
|
|
248
|
-
const popoverRect = this.overlayRef.overlayElement.getBoundingClientRect();
|
|
249
|
-
let arrowOffset = 0;
|
|
250
|
-
// If popover is top/bottom, arrow moves horizontally (left)
|
|
251
|
-
if (newPlacement.startsWith('top') ||
|
|
252
|
-
newPlacement.startsWith('bottom')) {
|
|
253
|
-
const triggerCenter = triggerRect.left + triggerRect.width / 2;
|
|
254
|
-
arrowOffset = triggerCenter - popoverRect.left;
|
|
255
|
-
}
|
|
256
|
-
// If popover is left/right, arrow moves vertically (top)
|
|
257
|
-
else {
|
|
258
|
-
const triggerCenter = triggerRect.top + triggerRect.height / 2;
|
|
259
|
-
arrowOffset = triggerCenter - popoverRect.top;
|
|
260
|
-
}
|
|
261
|
-
// 3. Pass the offset to the content component
|
|
262
|
-
componentRef.instance.arrowOffset = arrowOffset;
|
|
263
|
-
}
|
|
264
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
265
|
-
});
|
|
266
|
-
componentRef.instance.mouseEnterPopover.subscribe(() => {
|
|
267
|
-
if (this.closeTimeout)
|
|
268
|
-
clearTimeout(this.closeTimeout);
|
|
269
|
-
});
|
|
270
|
-
componentRef.instance.mouseLeavePopover.subscribe(() => this.handleMouseLeave());
|
|
271
|
-
if (config.trigger !== 'hover') {
|
|
272
|
-
this.overlayRef.backdropClick().subscribe(() => this.destroy());
|
|
273
|
-
}
|
|
274
|
-
const popoverId = `popover-${Math.random().toString(36).substring(2, 9)}`;
|
|
275
|
-
componentRef.location.nativeElement.setAttribute('id', popoverId);
|
|
276
|
-
trigger.setAttribute('aria-describedby', popoverId);
|
|
277
|
-
this.lastTriggerElement = trigger;
|
|
278
|
-
}
|
|
279
|
-
// Renamed from hide() to destroy() for clarity
|
|
280
|
-
destroy() {
|
|
281
|
-
if (!this.overlayRef)
|
|
282
|
-
return; // Prevent multiple calls
|
|
283
|
-
if (this.lastTriggerElement) {
|
|
284
|
-
this.lastTriggerElement.removeAttribute('aria-describedby');
|
|
285
|
-
this.lastTriggerElement = undefined;
|
|
286
|
-
}
|
|
287
|
-
this.positionSubscription?.unsubscribe();
|
|
288
|
-
this.overlayRef.dispose();
|
|
289
|
-
this.overlayRef = null;
|
|
290
|
-
}
|
|
291
|
-
getPlacementFromPosition(position) {
|
|
292
|
-
if (position.originY === 'top' && position.overlayY === 'bottom')
|
|
293
|
-
return 'top';
|
|
294
|
-
if (position.originY === 'bottom' && position.overlayY === 'top')
|
|
295
|
-
return 'bottom';
|
|
296
|
-
if (position.originX === 'start' && position.overlayX === 'end')
|
|
297
|
-
return 'left';
|
|
298
|
-
if (position.originX === 'end' && position.overlayX === 'start')
|
|
299
|
-
return 'right';
|
|
300
|
-
return 'bottom';
|
|
301
|
-
}
|
|
302
|
-
createPositionStrategy(origin, placement) {
|
|
303
|
-
let preferredPosition;
|
|
304
|
-
switch (placement) {
|
|
305
|
-
case 'top':
|
|
306
|
-
preferredPosition = positions[1];
|
|
307
|
-
break;
|
|
308
|
-
case 'right':
|
|
309
|
-
preferredPosition = positions[2];
|
|
310
|
-
break;
|
|
311
|
-
case 'left':
|
|
312
|
-
preferredPosition = positions[3];
|
|
313
|
-
break;
|
|
314
|
-
default:
|
|
315
|
-
preferredPosition = positions[0];
|
|
316
|
-
break;
|
|
317
|
-
}
|
|
318
|
-
return this.overlay
|
|
319
|
-
.position()
|
|
320
|
-
.flexibleConnectedTo(origin)
|
|
321
|
-
.withPositions([preferredPosition, ...positions])
|
|
322
|
-
.withPush(true);
|
|
323
|
-
}
|
|
324
|
-
//Document-level listeners for closing
|
|
325
|
-
onEscape() {
|
|
326
|
-
this.positionSubscription?.unsubscribe();
|
|
327
|
-
this.serviceSubscription?.unsubscribe();
|
|
328
|
-
this.destroy();
|
|
329
|
-
}
|
|
330
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibOverlayComponent, deps: [{ token: i1$1.Overlay }, { token: i0.Injector }, { token: OverlayService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
331
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: RuclibOverlayComponent, isStandalone: true, selector: "uxp-ruclib-overlay", inputs: { buttonText: "buttonText", rucInputData: "rucInputData", customTheme: "customTheme" }, host: { listeners: { "document:keydown:escape": "onEscape()" } }, viewQueries: [{ propertyName: "triggerButtonRef", first: true, predicate: MatButton, descendants: true, read: ElementRef }], ngImport: i0, template: "@if (buttonText) {\r\n <button\r\n mat-raised-button\r\n color=\"primary\"\r\n #triggerButton\r\n (click)=\"toggle()\"\r\n (mouseenter)=\"handleMouseEnter()\"\r\n (mouseleave)=\"handleMouseLeave()\"\r\n class=\"popover-trigger-btn\">\r\n {{ buttonText }}\r\n </button>\r\n}\r\n\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }] }); }
|
|
332
|
-
}
|
|
333
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibOverlayComponent, decorators: [{
|
|
334
|
-
type: Component,
|
|
335
|
-
args: [{ selector: 'uxp-ruclib-overlay', imports: [MatButtonModule, MatIconModule], template: "@if (buttonText) {\r\n <button\r\n mat-raised-button\r\n color=\"primary\"\r\n #triggerButton\r\n (click)=\"toggle()\"\r\n (mouseenter)=\"handleMouseEnter()\"\r\n (mouseleave)=\"handleMouseLeave()\"\r\n class=\"popover-trigger-btn\">\r\n {{ buttonText }}\r\n </button>\r\n}\r\n\r\n" }]
|
|
336
|
-
}], ctorParameters: () => [{ type: i1$1.Overlay }, { type: i0.Injector }, { type: OverlayService }], propDecorators: { buttonText: [{
|
|
337
|
-
type: Input
|
|
338
|
-
}], rucInputData: [{
|
|
339
|
-
type: Input
|
|
340
|
-
}], customTheme: [{
|
|
341
|
-
type: Input
|
|
342
|
-
}], triggerButtonRef: [{
|
|
343
|
-
type: ViewChild,
|
|
344
|
-
args: [MatButton, { read: ElementRef }]
|
|
345
|
-
}], onEscape: [{
|
|
346
|
-
type: HostListener,
|
|
347
|
-
args: ['document:keydown:escape']
|
|
348
|
-
}] } });
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Generated bundle index. Do not edit.
|
|
352
|
-
*/
|
|
353
|
-
|
|
354
|
-
export { OVERLAY_CONTROL, OverlayContentComponent, OverlayService, RuclibOverlayComponent };
|
|
355
|
-
//# sourceMappingURL=ruc-lib-overlay.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ruc-lib-overlay.mjs","sources":["../../src/lib/model/overlay.types.ts","../../src/lib/service/overlay.service.ts","../../src/lib/ruc-overlay-chart/ruc-overlay-chart.component.ts","../../src/lib/ruc-overlay-chart/ruc-overlay-chart.component.html","../../src/lib/overlay-content/overlay-content.component.ts","../../src/lib/overlay-content/overlay-content.component.html","../../src/lib/constants/positions.ts","../../src/lib/ruclib-overlay/ruclib-overlay.component.ts","../../src/lib/ruclib-overlay/ruclib-overlay.component.html","../../src/ruc-lib-overlay.ts"],"sourcesContent":["import { InjectionToken, TemplateRef } from '@angular/core';\r\n\r\n/**\r\n* Defines the configuration options that a user can pass to the popover.\r\n* This is the public API of your component.\r\n*/\r\nexport interface OverlayConfig {\r\n placement?: 'top' | 'bottom' | 'left' | 'right' | string;\r\n overlayTitle?: string;\r\n content?: string | TemplateRef<any>;\r\n animation?: 'fade' | 'scale';\r\n trigger?: 'click' | 'hover';\r\n showCloseButton?: boolean;\r\n closeIcon?: string;\r\n tableData?: any[];\r\n tableClass?: string;\r\n closeDelay?:number,\r\n chartConfig?:any\r\n}\r\n\r\n/**\r\n* Defines the data packet that the PopoverService sends.\r\n* It contains the configuration AND the element to position against.\r\n* THIS IS THE ONE THE SERVICE USES.\r\n*/\r\nexport interface OverlayData {\r\n config: OverlayConfig;\r\n trigger: HTMLElement;\r\n}\r\n\r\n/**\r\n* Defines the data and controls passed to the dynamically created PopoverContentComponent.\r\n* It includes the config AND a callback function to close the popover.\r\n*/\r\nexport interface OverlayControl {\r\n config: OverlayConfig;\r\n close: () => void;\r\n}\r\n\r\n/**\r\n* The Injection Token used to provide the PopoverControl object to the\r\n* PopoverContentComponent. This is the correct, final version.\r\n*/\r\nexport const OVERLAY_CONTROL = new InjectionToken<OverlayControl>('OVERLAY_CONTROL');\r\n","import { OverlayData } from './../model/overlay.types';\r\nimport { Injectable } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class OverlayService {\r\n\r\n private popoverState = new Subject<OverlayData | null>();\r\n\r\n public popoverState$ = this.popoverState.asObservable();\r\n\r\n\r\n\r\n /**\r\n * Broadcasts a command to open a popover using the OverlayData structure.\r\n */\r\n open(config: OverlayData['config'], trigger: OverlayData['trigger']) {\r\n console.log(config, trigger);\r\n // The service's responsibility is to bundle the config and trigger\r\n // into a PopoverData object and send it.\r\n this.popoverState.next({ config, trigger });\r\n }\r\n\r\n /**\r\n * Broadcasts a command to close any currently open service-controlled popover.\r\n */\r\n close() {\r\n this.popoverState.next(null);\r\n }\r\n}\r\n","import {\r\n AfterViewInit,\r\n ChangeDetectionStrategy,\r\n Component,\r\n Input,\r\n OnDestroy\r\n} from '@angular/core';\r\nimport Chart from 'chart.js/auto';\r\n\r\n\r\n@Component({\r\n selector: 'uxp-ruc-overlay-chart',\r\n imports: [],\r\n templateUrl: './ruc-overlay-chart.component.html',\r\n styleUrl: './ruc-overlay-chart.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class RucOverlayChartComponent implements AfterViewInit, OnDestroy {\r\n chart: any;\r\n @Input() index?:number = 0;\r\n @Input() chartConfig: any;\r\n\r\n ngAfterViewInit(): void {\r\n if(this.chartConfig) {\r\n this.chart = new Chart('canvas' + this.index, this.chartConfig);\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.chart?.destroy();\r\n this.chart = null;\r\n this.chartConfig = null;\r\n }\r\n}\r\n","<div style=\"position: relative; height:220px;\">\r\n <canvas id=\"canvas{{index}}\">{{chart}}</canvas>\r\n</div>\r\n","import { MatIconModule } from '@angular/material/icon';\r\nimport {\r\n Component,\r\n EventEmitter,\r\n HostBinding,\r\n Inject,\r\n Input,\r\n OnInit,\r\n Output,\r\n TemplateRef,\r\n} from '@angular/core';\r\nimport {\r\n animate,\r\n state,\r\n style,\r\n transition,\r\n trigger,\r\n} from '@angular/animations';\r\nimport { OVERLAY_CONTROL, OverlayControl } from '../model/overlay.types';\r\nimport { PopoverPlacement } from '../ruclib-overlay/ruclib-overlay.component';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RucOverlayChartComponent } from '../ruc-overlay-chart/ruc-overlay-chart.component';\r\nimport { MatCardModule } from '@angular/material/card';\r\nimport { MatButtonModule } from '@angular/material/button';\r\n@Component({\r\n selector: 'uxp-overlay-content',\r\n imports: [CommonModule, RucOverlayChartComponent, MatCardModule, MatIconModule, MatButtonModule],\r\n templateUrl: './overlay-content.component.html',\r\n styleUrl: './overlay-content.component.scss',\r\n animations: [\r\n trigger('popoverAnimation', [\r\n state('void', style({ transform: 'scale(0.9)', opacity: 0 })),\r\n state('enter-scale', style({ transform: 'scale(1)', opacity: 1 })),\r\n state('enter-fade', style({ opacity: 1 })),\r\n transition('void => enter-scale', animate('150ms cubic-bezier(0, 0, 0.2, 1)')),\r\n transition('void => enter-fade', [\r\n style({ opacity: 0, transform: 'translateY(10px)' }),\r\n animate('500ms', style({ opacity: 1, transform: 'translateY(0)' })),\r\n ]),\r\n transition('* => void', [\r\n animate('500ms', style({ opacity: 0, transform: 'translateY(10px)' })),\r\n ]),\r\n ]),\r\n ]\r\n})\r\nexport class OverlayContentComponent implements OnInit {\r\n public actualPlacement: string | PopoverPlacement = 'bottom';\r\n public tableHeaders:any[]=[];\r\n @Input() customTheme!:string;\r\n public arrowOffset =0;\r\n\r\n @Output() mouseEnterPopover = new EventEmitter<void>();\r\n @Output() mouseLeavePopover = new EventEmitter<void>();\r\n\r\n\r\n ngOnInit(): void {\r\n if(this.control.config.tableData) {\r\n this.getTableHeaders();\r\n }\r\n }\r\n\r\n @HostBinding('@popoverAnimation')\r\n get animationState() {\r\n return this.control.config.animation === 'scale'\r\n ? 'enter-scale'\r\n : 'enter-fade';\r\n }\r\n\r\n constructor(@Inject(OVERLAY_CONTROL) public control: OverlayControl) {\r\n this.actualPlacement = this.control.config.placement || 'bottom';\r\n }\r\n\r\n // Helper to check if content is a TemplateRef\r\n isTemplateRef(content: any): content is TemplateRef<any> {\r\n return content instanceof TemplateRef;\r\n }\r\n\r\n // Helper to get keys for the table header, robustly\r\n getTableHeaders(): void {\r\n const tempData = this.control.config.tableData;\r\n\r\n if (!tempData || tempData.length === 0) {\r\n this.tableHeaders = [];\r\n return;\r\n }\r\n // Assumes all objects in the array have the same shape\r\n this.tableHeaders = Object.keys(tempData[0]);\r\n }\r\n}\r\n\r\n","<mat-card class=\"popover-container\" class={{customTheme}} (click)=\"$event.stopPropagation()\">\r\n\r\n <div class=\"popover-arrow\"\r\n [attr.data-placement]=\"actualPlacement\"\r\n [style.left.px]=\"(actualPlacement.startsWith('top') || actualPlacement.startsWith('bottom')) ? arrowOffset : null\"\r\n [style.top.px]=\"(actualPlacement.startsWith('left') || actualPlacement.startsWith('right')) ? arrowOffset : null\">\r\n </div>\r\n <!-- Header with optional title and close button -->\r\n\r\n @if (\r\n control.config.overlayTitle ||\r\n control.config.showCloseButton ||\r\n control.config.closeIcon\r\n ) {\r\n <mat-card-header\r\n class=\"popover-header\"\r\n >\r\n @if (control.config.overlayTitle) {\r\n <mat-card-title class=\"popover-title\">{{ control.config.overlayTitle }}</mat-card-title>\r\n }\r\n @if (control.config.showCloseButton && control.config.closeIcon) {\r\n <button mat-icon-button class=\"close-btn\" (click)=\"control.close()\" color=\"primary\" aria-label=\"Close popover icon\">\r\n <mat-icon>{{ control.config.closeIcon }}</mat-icon>\r\n </button>\r\n }\r\n </mat-card-header>\r\n }\r\n\r\n\r\n <!-- Body with dynamic content -->\r\n <mat-card-content class=\"popover-body\">\r\n <!-- Case 1: Content is a simple string -->\r\n @if (\r\n !isTemplateRef(control.config.content) && !control.config.tableData\r\n ) {\r\n {{ control.config.content }}\r\n }\r\n\r\n <!-- Case 2: Content is a TemplateRef -->\r\n @if (isTemplateRef(control.config.content)) {\r\n <ng-container *ngTemplateOutlet=\"control.config.content\"></ng-container>\r\n }\r\n\r\n @if (control.config.chartConfig) {\r\n <uxp-ruc-overlay-chart [chartConfig]=\"control.config.chartConfig\"></uxp-ruc-overlay-chart>\r\n }\r\n\r\n <!-- Case 3: Content is table data -->\r\n @if (control.config.tableData?.length) {\r\n <table\r\n class=\"popover-table\"\r\n [class]=\"control.config.tableClass || 'basic-table'\"\r\n >\r\n <thead>\r\n <tr>\r\n @for (header of this.tableHeaders!; track header) {\r\n <th\r\n >\r\n {{ header }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of control.config.tableData; track row) {\r\n <tr>\r\n @for (header of this.tableHeaders!; track header) {\r\n <td\r\n >\r\n {{ row[header] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </mat-card-content>\r\n</mat-card>\r\n","import { ConnectedPosition } from \"@angular/cdk/overlay\";\r\n\r\nexport const positions: ConnectedPosition[] = [\r\n { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 10 },\r\n { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -10 },\r\n { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 10 },\r\n { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -10 }\r\n ];\r\n","import {\r\n ConnectedPosition,\r\n ConnectionPositionPair,\r\n FlexibleConnectedPositionStrategy,\r\n Overlay,\r\n OverlayRef,\r\n} from '@angular/cdk/overlay';\r\nimport {\r\n Component,\r\n ElementRef,\r\n HostListener,\r\n Injector,\r\n Input,\r\n OnDestroy,\r\n OnInit,\r\n ViewChild,\r\n} from '@angular/core';\r\nimport {\r\n OVERLAY_CONTROL,\r\n OverlayConfig,\r\n OverlayControl,\r\n OverlayData,\r\n} from '../model/overlay.types';\r\nimport { filter, Subscription } from 'rxjs';\r\nimport { ComponentPortal } from '@angular/cdk/portal';\r\nimport { OverlayService } from '../service/overlay.service';\r\nimport { OverlayContentComponent } from '../overlay-content/overlay-content.component';\r\nimport { MatButton, MatButtonModule } from '@angular/material/button';\r\nimport { ESCAPE } from '@angular/cdk/keycodes';\r\nimport { positions } from '../constants/positions';\r\n\r\nexport type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';\r\nexport type PopoverAnimation = 'fade' | 'scale';\r\nexport type ChartType = 'doughnut' | 'pie' | 'bar';\r\n\r\nexport interface ChartModel {\r\n chartType: ChartType;\r\n data: any;\r\n}\r\n\r\n\r\nimport { MatIconModule } from '@angular/material/icon';\r\n\r\n@Component({\r\n selector: 'uxp-ruclib-overlay',\r\n imports: [MatButtonModule, MatIconModule],\r\n templateUrl: './ruclib-overlay.component.html',\r\n styleUrl: './ruclib-overlay.component.scss'\r\n})\r\nexport class RuclibOverlayComponent implements OnInit, OnDestroy {\r\n @Input() buttonText?: string;\r\n @Input() rucInputData: OverlayConfig = {\r\n content: 'Default content',\r\n };\r\n @Input() customTheme!: string;\r\n\r\n @ViewChild(MatButton, { read: ElementRef })\r\n private triggerButtonRef!: ElementRef;\r\n\r\n private overlayRef: OverlayRef | null = null;\r\n private serviceSubscription!: Subscription;\r\n private closeTimeout?: ReturnType<typeof setTimeout>; // Use the correct type\r\n private lastTriggerElement?: HTMLElement;\r\n private positionSubscription!: Subscription;\r\n\r\n constructor(\r\n private overlay: Overlay,\r\n private injector: Injector,\r\n private overlayService: OverlayService\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n if (!this.buttonText) {\r\n this.serviceSubscription = this.overlayService.popoverState$.subscribe(\r\n (data: any) => {\r\n if (data && !this.isOpen) {\r\n this.show(data.trigger, data.config);\r\n } else if (!data) {\r\n this.destroy();\r\n }\r\n }\r\n );\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.positionSubscription?.unsubscribe();\r\n this.serviceSubscription?.unsubscribe();\r\n this.destroy();\r\n }\r\n\r\n get isOpen(): boolean {\r\n return !!this.overlayRef;\r\n }\r\n\r\n // --- Trigger Handlers for self-contained button ---\r\n toggle(): void {\r\n if (this.rucInputData.trigger !== 'hover') {\r\n this.isOpen\r\n ? this.destroy()\r\n : this.show(this.triggerButtonRef.nativeElement, this.rucInputData);\r\n }\r\n }\r\n\r\n handleMouseEnter(): void {\r\n if (this.rucInputData.trigger === 'hover') {\r\n if (this.closeTimeout) clearTimeout(this.closeTimeout); // Clear any pending close command\r\n this.show(this.triggerButtonRef.nativeElement, this.rucInputData);\r\n }\r\n }\r\n\r\n handleMouseLeave(): void {\r\n if (this.rucInputData.trigger === 'hover') {\r\n // Use the configurable closeDelay\r\n const delay = this.rucInputData.closeDelay ?? 200;\r\n this.closeTimeout = setTimeout(() => this.destroy(), delay);\r\n }\r\n }\r\n\r\n private show(trigger: HTMLElement, config: OverlayConfig): void {\r\n if (this.isOpen) return;\r\n\r\n const positionStrategy = this.createPositionStrategy(\r\n trigger,\r\n config.placement || 'bottom'\r\n );\r\n this.overlayRef = this.overlay.create({\r\n positionStrategy,\r\n hasBackdrop: config.trigger !== 'hover',\r\n backdropClass: 'cdk-overlay-transparent-backdrop',\r\n scrollStrategy: this.overlay.scrollStrategies.reposition(),\r\n });\r\n\r\n this.overlayRef.keydownEvents().pipe(filter(event=> event.keyCode === ESCAPE)).subscribe(()=> this.destroy());\r\n\r\n const control: OverlayControl = { config, close: this.destroy.bind(this) };\r\n const injector = Injector.create({\r\n parent: this.injector,\r\n providers: [{ provide: OVERLAY_CONTROL, useValue: control }],\r\n });\r\n\r\n const portal = new ComponentPortal(OverlayContentComponent, null, injector);\r\n const componentRef = this.overlayRef.attach(portal);\r\n componentRef.instance.customTheme = this.customTheme;\r\n\r\n // --- START: MODIFICATION FOR DYNAMIC ARROW ---\r\n this.positionSubscription = positionStrategy.positionChanges.subscribe(\r\n (change) => {\r\n // 1. Get the new placement ('top', 'bottom', etc.)\r\n const newPlacement = this.getPlacementFromPosition(\r\n change.connectionPair\r\n );\r\n componentRef.instance.actualPlacement = newPlacement;\r\n\r\n // 2. Calculate the arrow's offset\r\n if (this.overlayRef) {\r\n const triggerRect = trigger.getBoundingClientRect();\r\n const popoverRect =\r\n this.overlayRef.overlayElement.getBoundingClientRect();\r\n\r\n let arrowOffset = 0;\r\n // If popover is top/bottom, arrow moves horizontally (left)\r\n if (\r\n newPlacement.startsWith('top') ||\r\n newPlacement.startsWith('bottom')\r\n ) {\r\n const triggerCenter = triggerRect.left + triggerRect.width / 2;\r\n arrowOffset = triggerCenter - popoverRect.left;\r\n }\r\n // If popover is left/right, arrow moves vertically (top)\r\n else {\r\n const triggerCenter = triggerRect.top + triggerRect.height / 2;\r\n arrowOffset = triggerCenter - popoverRect.top;\r\n }\r\n\r\n // 3. Pass the offset to the content component\r\n componentRef.instance.arrowOffset = arrowOffset;\r\n }\r\n\r\n componentRef.changeDetectorRef.detectChanges();\r\n }\r\n );\r\n\r\n componentRef.instance.mouseEnterPopover.subscribe(() => {\r\n if (this.closeTimeout) clearTimeout(this.closeTimeout);\r\n });\r\n componentRef.instance.mouseLeavePopover.subscribe(() =>\r\n this.handleMouseLeave()\r\n );\r\n\r\n if (config.trigger !== 'hover') {\r\n this.overlayRef.backdropClick().subscribe(() => this.destroy());\r\n }\r\n\r\n const popoverId = `popover-${Math.random().toString(36).substring(2, 9)}`;\r\n componentRef.location.nativeElement.setAttribute('id', popoverId);\r\n trigger.setAttribute('aria-describedby', popoverId);\r\n this.lastTriggerElement = trigger;\r\n }\r\n\r\n // Renamed from hide() to destroy() for clarity\r\n private destroy(): void {\r\n if (!this.overlayRef) return; // Prevent multiple calls\r\n\r\n if (this.lastTriggerElement) {\r\n this.lastTriggerElement.removeAttribute('aria-describedby');\r\n this.lastTriggerElement = undefined;\r\n }\r\n this.positionSubscription?.unsubscribe();\r\n this.overlayRef.dispose();\r\n this.overlayRef = null;\r\n }\r\n\r\n private getPlacementFromPosition(\r\n position: ConnectionPositionPair\r\n ): PopoverPlacement {\r\n if (position.originY === 'top' && position.overlayY === 'bottom')\r\n return 'top';\r\n if (position.originY === 'bottom' && position.overlayY === 'top')\r\n return 'bottom';\r\n if (position.originX === 'start' && position.overlayX === 'end')\r\n return 'left';\r\n if (position.originX === 'end' && position.overlayX === 'start')\r\n return 'right';\r\n return 'bottom';\r\n }\r\n\r\n private createPositionStrategy(\r\n origin: HTMLElement,\r\n placement: string\r\n ): FlexibleConnectedPositionStrategy {\r\n let preferredPosition: ConnectedPosition;\r\n switch (placement) {\r\n case 'top':\r\n preferredPosition = positions[1];\r\n break;\r\n case 'right':\r\n preferredPosition = positions[2];\r\n break;\r\n case 'left':\r\n preferredPosition = positions[3];\r\n break;\r\n default:\r\n preferredPosition = positions[0];\r\n break;\r\n }\r\n\r\n return this.overlay\r\n .position()\r\n .flexibleConnectedTo(origin)\r\n .withPositions([preferredPosition, ...positions])\r\n .withPush(true);\r\n }\r\n\r\n //Document-level listeners for closing\r\n @HostListener('document:keydown:escape')\r\n onEscape(): void {\r\n this.positionSubscription?.unsubscribe();\r\n this.serviceSubscription?.unsubscribe();\r\n this.destroy();\r\n }\r\n}\r\n","@if (buttonText) {\r\n <button\r\n mat-raised-button\r\n color=\"primary\"\r\n #triggerButton\r\n (click)=\"toggle()\"\r\n (mouseenter)=\"handleMouseEnter()\"\r\n (mouseleave)=\"handleMouseLeave()\"\r\n class=\"popover-trigger-btn\">\r\n {{ buttonText }}\r\n </button>\r\n}\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2.OverlayService","i3"],"mappings":"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"}
|