@patter/ngx-components 0.5.2 → 0.5.4
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/esm2022/lib/dialog/ptr-dialog/ptr-dialog.component.mjs +45 -0
- package/esm2022/lib/dialog/ptr-dialog.service.mjs +47 -0
- package/esm2022/lib/dialog/ptr-tooltip/ptr-tooltip.component.mjs +31 -0
- package/esm2022/lib/forms/form/form.component.mjs +8 -6
- package/esm2022/lib/loading-spinner/loading-spinner.component.mjs +12 -0
- package/esm2022/lib/loading-spinner/loading-spinner.directive.mjs +83 -0
- package/esm2022/lib/menu/menu.component.mjs +3 -3
- package/esm2022/lib/ptr-button/ptr-button.component.mjs +108 -0
- package/esm2022/lib/ptr-title/ptr-title.component.mjs +3 -3
- package/esm2022/lib/services/loading.service.mjs +83 -0
- package/esm2022/public-api.mjs +8 -2
- package/fesm2022/patter-ngx-components.mjs +402 -16
- package/fesm2022/patter-ngx-components.mjs.map +1 -1
- package/lib/dialog/ptr-dialog/ptr-dialog.component.d.ts +15 -0
- package/lib/dialog/ptr-dialog.service.d.ts +17 -0
- package/lib/dialog/ptr-tooltip/ptr-tooltip.component.d.ts +11 -0
- package/lib/loading-spinner/loading-spinner.component.d.ts +5 -0
- package/lib/loading-spinner/loading-spinner.directive.d.ts +20 -0
- package/lib/ptr-button/ptr-button.component.d.ts +28 -0
- package/lib/services/loading.service.d.ts +36 -0
- package/package.json +1 -1
- package/patter-ngx-components-0.5.4.tgz +0 -0
- package/public-api.d.ts +7 -0
- package/patter-ngx-components-0.5.2.tgz +0 -0
|
@@ -1,26 +1,129 @@
|
|
|
1
1
|
import * as i1 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { Component, ChangeDetectionStrategy, Input, EventEmitter, inject, ChangeDetectorRef, DestroyRef,
|
|
4
|
+
import { Component, ChangeDetectionStrategy, Input, signal, EventEmitter, computed, HostBinding, Output, inject, ChangeDetectorRef, DestroyRef, ElementRef, ViewContainerRef, Renderer2, Directive, Injectable, ViewChild, createComponent } from '@angular/core';
|
|
5
5
|
import * as i2 from '@angular/router';
|
|
6
|
-
import { RouterModule, Router, ActivatedRoute, TitleStrategy, NavigationEnd } from '@angular/router';
|
|
6
|
+
import { RouterModule, RouterLink, Router, ActivatedRoute, TitleStrategy, NavigationEnd } from '@angular/router';
|
|
7
7
|
import * as i2$1 from '@angular/forms';
|
|
8
8
|
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
|
|
9
9
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
10
|
-
import { Observable, filter, map } from 'rxjs';
|
|
10
|
+
import { Observable, filter, map, Subject } from 'rxjs';
|
|
11
11
|
|
|
12
12
|
class PtrMenuComponent {
|
|
13
13
|
menuItems = [];
|
|
14
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
15
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.
|
|
14
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.4", type: PtrMenuComponent, isStandalone: true, selector: "ptr-menu", inputs: { menuItems: "menuItems" }, ngImport: i0, template: "<nav class=\"ptr-menu\">\r\n <ul class=\"menu\">\r\n <li class=\"menu-item\" *ngFor=\"let item of menuItems\" routerLinkActive=\"current_page_item\"\r\n [routerLinkActiveOptions]=\"{exact: true}\">\r\n <a [routerLink]=\"item.link || '#'\">{{item.label}}</a>\r\n </li>\r\n </ul>\r\n</nav>\r\n", styles: [".menu{display:flex;flex-direction:row;gap:var(--wp--custom--content--gap, 40px);align-items:center}.menu>ul{display:flex;flex-direction:row;gap:var(--wp--custom--content--gap, 40px);align-items:center}.menu--vertical{flex-direction:column;align-items:flex-start;gap:calc(var(--wp--custom--content--gap, 40px) / 2)}.menu--vertical>ul{flex-direction:column;align-items:flex-start;gap:calc(var(--wp--custom--content--gap, 40px) / 2)}.menu li.current-menu-item>a,.menu li.current_page_item>a,.menu li.current-menu-parent>a{opacity:1;font-weight:700}.menu a{transition:color .33s}.menu a:hover,.menu a:focus{text-decoration:none}.menu a{position:relative;text-decoration:none;padding:8px 0;font-family:var(--wp--preset--font-family--heading-font);letter-spacing:-.72px;color:var(--ptr-menu-color, var(--wp--preset--color--black))}.menu a:before,.menu a:after{content:\"\";position:absolute;bottom:2px;left:0;right:0;height:2px;background-color:var(--wp--preset--color--primary)}.menu a:before{opacity:0;transform:translateY(-8px);transition:transform 0s cubic-bezier(.175,.885,.32,1.275),opacity 0s}.menu a:after{opacity:0;transform:translateY(4px);transition:transform .2s cubic-bezier(.175,.885,.32,1.275),opacity .2s}.menu a:hover:before,.menu a:hover:after,.menu a:focus:before,.menu a:focus:after{opacity:1;transform:translateY(0)}.menu a:hover:before,.menu a:focus:before{transition:transform .2s cubic-bezier(.175,.885,.32,1.275),opacity .2s}.menu a:hover:after,.menu a:focus:after{transition:transform 0s .2s cubic-bezier(.175,.885,.32,1.275),opacity 0s .2s}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
16
16
|
}
|
|
17
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrMenuComponent, decorators: [{
|
|
18
18
|
type: Component,
|
|
19
19
|
args: [{ selector: 'ptr-menu', standalone: true, imports: [CommonModule, RouterModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav class=\"ptr-menu\">\r\n <ul class=\"menu\">\r\n <li class=\"menu-item\" *ngFor=\"let item of menuItems\" routerLinkActive=\"current_page_item\"\r\n [routerLinkActiveOptions]=\"{exact: true}\">\r\n <a [routerLink]=\"item.link || '#'\">{{item.label}}</a>\r\n </li>\r\n </ul>\r\n</nav>\r\n", styles: [".menu{display:flex;flex-direction:row;gap:var(--wp--custom--content--gap, 40px);align-items:center}.menu>ul{display:flex;flex-direction:row;gap:var(--wp--custom--content--gap, 40px);align-items:center}.menu--vertical{flex-direction:column;align-items:flex-start;gap:calc(var(--wp--custom--content--gap, 40px) / 2)}.menu--vertical>ul{flex-direction:column;align-items:flex-start;gap:calc(var(--wp--custom--content--gap, 40px) / 2)}.menu li.current-menu-item>a,.menu li.current_page_item>a,.menu li.current-menu-parent>a{opacity:1;font-weight:700}.menu a{transition:color .33s}.menu a:hover,.menu a:focus{text-decoration:none}.menu a{position:relative;text-decoration:none;padding:8px 0;font-family:var(--wp--preset--font-family--heading-font);letter-spacing:-.72px;color:var(--ptr-menu-color, var(--wp--preset--color--black))}.menu a:before,.menu a:after{content:\"\";position:absolute;bottom:2px;left:0;right:0;height:2px;background-color:var(--wp--preset--color--primary)}.menu a:before{opacity:0;transform:translateY(-8px);transition:transform 0s cubic-bezier(.175,.885,.32,1.275),opacity 0s}.menu a:after{opacity:0;transform:translateY(4px);transition:transform .2s cubic-bezier(.175,.885,.32,1.275),opacity .2s}.menu a:hover:before,.menu a:hover:after,.menu a:focus:before,.menu a:focus:after{opacity:1;transform:translateY(0)}.menu a:hover:before,.menu a:focus:before{transition:transform .2s cubic-bezier(.175,.885,.32,1.275),opacity .2s}.menu a:hover:after,.menu a:focus:after{transition:transform 0s .2s cubic-bezier(.175,.885,.32,1.275),opacity 0s .2s}\n"] }]
|
|
20
20
|
}], propDecorators: { menuItems: [{
|
|
21
21
|
type: Input
|
|
22
22
|
}] } });
|
|
23
23
|
|
|
24
|
+
class PtrButtonComponent {
|
|
25
|
+
get hostClasses() {
|
|
26
|
+
const hostClass = [];
|
|
27
|
+
if (this.style() === 'secondary') {
|
|
28
|
+
hostClass.push('is-style-outline');
|
|
29
|
+
}
|
|
30
|
+
if (this.style() === 'error') {
|
|
31
|
+
hostClass.push('is-style-error-button');
|
|
32
|
+
}
|
|
33
|
+
if (this.style() === 'icon') {
|
|
34
|
+
hostClass.push('is-style-icon-button');
|
|
35
|
+
}
|
|
36
|
+
if (this.smallSize()) {
|
|
37
|
+
hostClass.push('is-style-smaller-element');
|
|
38
|
+
}
|
|
39
|
+
return hostClass.join(' ');
|
|
40
|
+
}
|
|
41
|
+
style = signal('normal');
|
|
42
|
+
type = signal('button');
|
|
43
|
+
disabled = signal(false);
|
|
44
|
+
href = signal(null);
|
|
45
|
+
routerLink = signal(null);
|
|
46
|
+
additionalClasses = signal('');
|
|
47
|
+
smallSize = signal(false);
|
|
48
|
+
set buttonStyle(value) {
|
|
49
|
+
this.style.set(value);
|
|
50
|
+
}
|
|
51
|
+
set buttonType(value) {
|
|
52
|
+
this.type.set(value);
|
|
53
|
+
}
|
|
54
|
+
set isDisabled(value) {
|
|
55
|
+
this.disabled.set(value);
|
|
56
|
+
}
|
|
57
|
+
set hrefLink(value) {
|
|
58
|
+
this.href.set(value);
|
|
59
|
+
}
|
|
60
|
+
set routerLinkValue(value) {
|
|
61
|
+
this.routerLink.set(value);
|
|
62
|
+
}
|
|
63
|
+
set extraClasses(value) {
|
|
64
|
+
this.additionalClasses.set(value);
|
|
65
|
+
}
|
|
66
|
+
set isSmallSize(value) {
|
|
67
|
+
if (value) {
|
|
68
|
+
this.smallSize.set(true);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
set isIconButton(value) {
|
|
72
|
+
if (value) {
|
|
73
|
+
this.style.set('icon');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
clicked = new EventEmitter();
|
|
77
|
+
isLink = computed(() => !!this.href() || !!this.routerLink());
|
|
78
|
+
buttonClasses = computed(() => {
|
|
79
|
+
const classes = ['wp-block-button__link'];
|
|
80
|
+
if (this.style() !== 'normal') {
|
|
81
|
+
classes.push(`wp-block-button__link--${this.style()}`);
|
|
82
|
+
}
|
|
83
|
+
if (this.disabled() && this.isLink()) {
|
|
84
|
+
classes.push('disabled');
|
|
85
|
+
}
|
|
86
|
+
if (this.additionalClasses()) {
|
|
87
|
+
classes.push(this.additionalClasses());
|
|
88
|
+
}
|
|
89
|
+
return classes.join(' ');
|
|
90
|
+
});
|
|
91
|
+
onClick(event) {
|
|
92
|
+
if (this.disabled()) {
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this.clicked.emit(event);
|
|
97
|
+
}
|
|
98
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
99
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: PtrButtonComponent, isStandalone: true, selector: "ptr-button", inputs: { buttonStyle: "buttonStyle", buttonType: "buttonType", isDisabled: "isDisabled", hrefLink: "hrefLink", routerLinkValue: "routerLinkValue", extraClasses: "extraClasses", isSmallSize: "isSmallSize", isIconButton: "isIconButton" }, outputs: { clicked: "clicked" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: "<ng-template #contentTpl>\r\n <ng-content></ng-content>\r\n</ng-template>\r\n\r\n@if (isLink()) {\r\n<a [attr.href]=\"href()\" [routerLink]=\"routerLink()\" [class]=\"buttonClasses()\" [attr.disabled]=\"disabled() ? '' : null\"\r\n (click)=\"onClick($event)\">\r\n <ng-container [ngTemplateOutlet]=\"contentTpl\"></ng-container>\r\n</a>\r\n} @else {\r\n<button [type]=\"type()\" [class]=\"buttonClasses()\" [disabled]=\"disabled()\" (click)=\"onClick($event)\">\r\n <ng-container [ngTemplateOutlet]=\"contentTpl\"></ng-container>\r\n</button>\r\n}", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
100
|
+
}
|
|
101
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrButtonComponent, decorators: [{
|
|
102
|
+
type: Component,
|
|
103
|
+
args: [{ selector: 'ptr-button', standalone: true, imports: [CommonModule, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #contentTpl>\r\n <ng-content></ng-content>\r\n</ng-template>\r\n\r\n@if (isLink()) {\r\n<a [attr.href]=\"href()\" [routerLink]=\"routerLink()\" [class]=\"buttonClasses()\" [attr.disabled]=\"disabled() ? '' : null\"\r\n (click)=\"onClick($event)\">\r\n <ng-container [ngTemplateOutlet]=\"contentTpl\"></ng-container>\r\n</a>\r\n} @else {\r\n<button [type]=\"type()\" [class]=\"buttonClasses()\" [disabled]=\"disabled()\" (click)=\"onClick($event)\">\r\n <ng-container [ngTemplateOutlet]=\"contentTpl\"></ng-container>\r\n</button>\r\n}" }]
|
|
104
|
+
}], propDecorators: { hostClasses: [{
|
|
105
|
+
type: HostBinding,
|
|
106
|
+
args: ['class']
|
|
107
|
+
}], buttonStyle: [{
|
|
108
|
+
type: Input
|
|
109
|
+
}], buttonType: [{
|
|
110
|
+
type: Input
|
|
111
|
+
}], isDisabled: [{
|
|
112
|
+
type: Input
|
|
113
|
+
}], hrefLink: [{
|
|
114
|
+
type: Input
|
|
115
|
+
}], routerLinkValue: [{
|
|
116
|
+
type: Input
|
|
117
|
+
}], extraClasses: [{
|
|
118
|
+
type: Input
|
|
119
|
+
}], isSmallSize: [{
|
|
120
|
+
type: Input
|
|
121
|
+
}], isIconButton: [{
|
|
122
|
+
type: Input
|
|
123
|
+
}], clicked: [{
|
|
124
|
+
type: Output
|
|
125
|
+
}] } });
|
|
126
|
+
|
|
24
127
|
class PtrFormComponent {
|
|
25
128
|
config;
|
|
26
129
|
loading = false;
|
|
@@ -78,15 +181,16 @@ class PtrFormComponent {
|
|
|
78
181
|
this.flatOptions[fieldName] = options;
|
|
79
182
|
}
|
|
80
183
|
}
|
|
81
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
82
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.
|
|
184
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
185
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.4", type: PtrFormComponent, isStandalone: true, selector: "ptr-form", inputs: { config: "config", loading: "loading", error: "error" }, outputs: { formSubmit: "formSubmit", formGroupCreated: "formGroupCreated" }, ngImport: i0, template: "<div [class]=\"'gform_wrapper ' + config.formClass\">\r\n\r\n <div class=\"gform_validation_errors\" *ngIf=\"error\">\r\n <h2 class=\"gform_submission_error hide_summary\">{{error}}</h2>\r\n </div>\r\n\r\n <div *ngIf=\"config.title\" class=\"gform_heading\">\r\n <h2 class=\"gform_title\">{{ config.title }}</h2>\r\n </div>\r\n\r\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\r\n\r\n <div class=\"gform_fields\">\r\n\r\n <ng-container *ngFor=\"let field of config.fields\">\r\n\r\n <div class=\"gfield gfield--width-{{field.size}}\" [class.gform_hidden]=\"field.type === 'hidden'\"\r\n [class.gfield_error]=\"formGroup.get(field.name)?.invalid && formGroup.get(field.name)?.touched\">\r\n\r\n <label class=\"gfield_label gform-field-label\" [for]=\"field.name\">{{ field.label }}</label>\r\n\r\n <ng-container [ngSwitch]=\"field.type\">\r\n\r\n <input *ngSwitchCase=\"'text'\" [formControlName]=\"field.name\" type=\"text\" [id]=\"field.name\" />\r\n\r\n <textarea *ngSwitchCase=\"'textarea'\" [id]=\"field.name\" [formControlName]=\"field.name\"></textarea>\r\n\r\n <input *ngSwitchCase=\"'date'\" [formControlName]=\"field.name\" type=\"date\" [id]=\"field.name\" />\r\n\r\n <input *ngSwitchCase=\"'number'\" [formControlName]=\"field.name\" type=\"number\" [id]=\"field.name\" />\r\n\r\n <input *ngSwitchCase=\"'email'\" [formControlName]=\"field.name\" type=\"email\" [id]=\"field.name\" />\r\n\r\n <input *ngSwitchCase=\"'password'\" [formControlName]=\"field.name\" type=\"password\" [id]=\"field.name\" />\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <select [formControlName]=\"field.name\" [id]=\"field.name\">\r\n <!-- Render grouped options -->\r\n <optgroup *ngFor=\"let group of groupedOptions[field.name]\" [label]=\"group.groupLabel\">\r\n <option *ngFor=\"let option of group.options\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </option>\r\n </optgroup>\r\n <!-- Render flat options -->\r\n <option *ngFor=\"let option of flatOptions[field.name]\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </option>\r\n </select>\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n <div class=\"gfield_description validation_message gfield_validation_message\"\r\n *ngIf=\"formGroup.get(field.name)?.invalid && formGroup.get(field.name)?.touched\">\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['required']\">This field is required.</ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['email']\">Please enter a valid email\r\n address.</ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['minlength']\">\r\n Minimum length is {{ formGroup.get(field.name)?.errors?.['minlength'].requiredLength }} characters.\r\n </ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['maxlength']\">\r\n Maximum length is {{ formGroup.get(field.name)?.errors?.['maxlength'].requiredLength }} characters.\r\n </ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['pattern']\">\r\n Please match the required format.\r\n </ng-container>\r\n </div>\r\n\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"gform_footer\">\r\n <ptr-button buttonType=\"submit\" [isDisabled]=\"loading || !formGroup.valid\">{{config.submitText}}</ptr-button>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: PtrButtonComponent, selector: "ptr-button", inputs: ["buttonStyle", "buttonType", "isDisabled", "hrefLink", "routerLinkValue", "extraClasses", "isSmallSize", "isIconButton"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
83
186
|
}
|
|
84
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
187
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrFormComponent, decorators: [{
|
|
85
188
|
type: Component,
|
|
86
189
|
args: [{ selector: 'ptr-form', standalone: true, imports: [
|
|
87
190
|
CommonModule,
|
|
88
|
-
ReactiveFormsModule
|
|
89
|
-
|
|
191
|
+
ReactiveFormsModule,
|
|
192
|
+
PtrButtonComponent
|
|
193
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"'gform_wrapper ' + config.formClass\">\r\n\r\n <div class=\"gform_validation_errors\" *ngIf=\"error\">\r\n <h2 class=\"gform_submission_error hide_summary\">{{error}}</h2>\r\n </div>\r\n\r\n <div *ngIf=\"config.title\" class=\"gform_heading\">\r\n <h2 class=\"gform_title\">{{ config.title }}</h2>\r\n </div>\r\n\r\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\r\n\r\n <div class=\"gform_fields\">\r\n\r\n <ng-container *ngFor=\"let field of config.fields\">\r\n\r\n <div class=\"gfield gfield--width-{{field.size}}\" [class.gform_hidden]=\"field.type === 'hidden'\"\r\n [class.gfield_error]=\"formGroup.get(field.name)?.invalid && formGroup.get(field.name)?.touched\">\r\n\r\n <label class=\"gfield_label gform-field-label\" [for]=\"field.name\">{{ field.label }}</label>\r\n\r\n <ng-container [ngSwitch]=\"field.type\">\r\n\r\n <input *ngSwitchCase=\"'text'\" [formControlName]=\"field.name\" type=\"text\" [id]=\"field.name\" />\r\n\r\n <textarea *ngSwitchCase=\"'textarea'\" [id]=\"field.name\" [formControlName]=\"field.name\"></textarea>\r\n\r\n <input *ngSwitchCase=\"'date'\" [formControlName]=\"field.name\" type=\"date\" [id]=\"field.name\" />\r\n\r\n <input *ngSwitchCase=\"'number'\" [formControlName]=\"field.name\" type=\"number\" [id]=\"field.name\" />\r\n\r\n <input *ngSwitchCase=\"'email'\" [formControlName]=\"field.name\" type=\"email\" [id]=\"field.name\" />\r\n\r\n <input *ngSwitchCase=\"'password'\" [formControlName]=\"field.name\" type=\"password\" [id]=\"field.name\" />\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <select [formControlName]=\"field.name\" [id]=\"field.name\">\r\n <!-- Render grouped options -->\r\n <optgroup *ngFor=\"let group of groupedOptions[field.name]\" [label]=\"group.groupLabel\">\r\n <option *ngFor=\"let option of group.options\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </option>\r\n </optgroup>\r\n <!-- Render flat options -->\r\n <option *ngFor=\"let option of flatOptions[field.name]\" [value]=\"option.value\">\r\n {{ option.label }}\r\n </option>\r\n </select>\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n <div class=\"gfield_description validation_message gfield_validation_message\"\r\n *ngIf=\"formGroup.get(field.name)?.invalid && formGroup.get(field.name)?.touched\">\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['required']\">This field is required.</ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['email']\">Please enter a valid email\r\n address.</ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['minlength']\">\r\n Minimum length is {{ formGroup.get(field.name)?.errors?.['minlength'].requiredLength }} characters.\r\n </ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['maxlength']\">\r\n Maximum length is {{ formGroup.get(field.name)?.errors?.['maxlength'].requiredLength }} characters.\r\n </ng-container>\r\n <ng-container *ngIf=\"formGroup.get(field.name)?.errors?.['pattern']\">\r\n Please match the required format.\r\n </ng-container>\r\n </div>\r\n\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"gform_footer\">\r\n <ptr-button buttonType=\"submit\" [isDisabled]=\"loading || !formGroup.valid\">{{config.submitText}}</ptr-button>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n" }]
|
|
90
194
|
}], propDecorators: { config: [{
|
|
91
195
|
type: Input
|
|
92
196
|
}], loading: [{
|
|
@@ -121,10 +225,10 @@ class PtrTitleComponent {
|
|
|
121
225
|
}
|
|
122
226
|
return route;
|
|
123
227
|
}
|
|
124
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
125
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.
|
|
228
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
229
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.4", type: PtrTitleComponent, isStandalone: true, selector: "ptr-title", ngImport: i0, template: '<header class="entry-header is-layout-constrained my-3" *ngIf="!(hideTitle$ | async)"><h1 class="entry-title">{{ title$ | async }}</h1></header>', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
126
230
|
}
|
|
127
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
231
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrTitleComponent, decorators: [{
|
|
128
232
|
type: Component,
|
|
129
233
|
args: [{
|
|
130
234
|
selector: 'ptr-title',
|
|
@@ -135,14 +239,296 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImpor
|
|
|
135
239
|
}]
|
|
136
240
|
}] });
|
|
137
241
|
|
|
242
|
+
class PtrLoadingSpinnerComponent {
|
|
243
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrLoadingSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
244
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.4", type: PtrLoadingSpinnerComponent, isStandalone: true, selector: "ptr-loading-spinner", ngImport: i0, template: `<div class="vdx-progress-spinner"></div>`, isInline: true, styles: [":host{display:inline-block;line-height:0}.vdx-progress-spinner{display:inline-block;width:25px;height:25px;transform:scaleZ(1)}.vdx-progress-spinner:before{position:absolute;content:\"\";background-image:url(\"data:image/svg+xml,%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 40 40' style='enable-background:new 0 0 40 40;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill:%23272e3e;%7D%0A%3C/style%3E%3Ccircle class='st0' cx='34' cy='6' r='6'/%3E%3Ccircle class='st0' cx='6' cy='6' r='6'/%3E%3Ccircle class='st0' cx='6' cy='34' r='6'/%3E%3Ccircle class='st0' cx='34' cy='34' r='6'/%3E%3C/svg%3E\");height:40px;width:40px;left:-8px;top:-8px;border:none;display:block;animation:loader-anim 1.5s 0s ease-in-out infinite}.vdx-progress-spinner:after{content:\"\";position:absolute;height:12px;width:12px;border:none;border-radius:12px;display:block;left:6px;top:6px;background-color:#272e3e;animation:loader-anim-dot 1.5s 0s ease-in-out infinite}@keyframes loader-anim{0%{transform:rotate(0) scale(0);opacity:.5}50%{transform:rotate(180deg) scale(1);opacity:1}to{transform:rotate(360deg) scale(0);opacity:.2}}@keyframes loader-anim-dot{0%{opacity:1}50%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
245
|
+
}
|
|
246
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrLoadingSpinnerComponent, decorators: [{
|
|
247
|
+
type: Component,
|
|
248
|
+
args: [{ selector: 'ptr-loading-spinner', standalone: true, imports: [CommonModule], template: `<div class="vdx-progress-spinner"></div>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block;line-height:0}.vdx-progress-spinner{display:inline-block;width:25px;height:25px;transform:scaleZ(1)}.vdx-progress-spinner:before{position:absolute;content:\"\";background-image:url(\"data:image/svg+xml,%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 40 40' style='enable-background:new 0 0 40 40;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill:%23272e3e;%7D%0A%3C/style%3E%3Ccircle class='st0' cx='34' cy='6' r='6'/%3E%3Ccircle class='st0' cx='6' cy='6' r='6'/%3E%3Ccircle class='st0' cx='6' cy='34' r='6'/%3E%3Ccircle class='st0' cx='34' cy='34' r='6'/%3E%3C/svg%3E\");height:40px;width:40px;left:-8px;top:-8px;border:none;display:block;animation:loader-anim 1.5s 0s ease-in-out infinite}.vdx-progress-spinner:after{content:\"\";position:absolute;height:12px;width:12px;border:none;border-radius:12px;display:block;left:6px;top:6px;background-color:#272e3e;animation:loader-anim-dot 1.5s 0s ease-in-out infinite}@keyframes loader-anim{0%{transform:rotate(0) scale(0);opacity:.5}50%{transform:rotate(180deg) scale(1);opacity:1}to{transform:rotate(360deg) scale(0);opacity:.2}}@keyframes loader-anim-dot{0%{opacity:1}50%{opacity:0}to{opacity:1}}\n"] }]
|
|
249
|
+
}] });
|
|
250
|
+
|
|
251
|
+
class PtrLoadingSpinnerDirective {
|
|
252
|
+
targetEl = inject(ElementRef);
|
|
253
|
+
viewContainerRef = inject(ViewContainerRef);
|
|
254
|
+
renderer = inject(Renderer2);
|
|
255
|
+
spinnerInstance;
|
|
256
|
+
overlay;
|
|
257
|
+
hostPosition = 'relative';
|
|
258
|
+
set ptrLoadingSpinner(loading) {
|
|
259
|
+
if (loading) {
|
|
260
|
+
this.addBlurEffect();
|
|
261
|
+
this.addOverlay();
|
|
262
|
+
this.addProgressSpinnerComponent();
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
this.removeBlurEffect();
|
|
266
|
+
this.removeOverlay();
|
|
267
|
+
this.removeProgressSpinnerComponent();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
ngOnDestroy() {
|
|
271
|
+
this.spinnerInstance?.destroy();
|
|
272
|
+
this.removeBlurEffect();
|
|
273
|
+
}
|
|
274
|
+
addProgressSpinnerComponent() {
|
|
275
|
+
this.spinnerInstance = this.viewContainerRef.createComponent(PtrLoadingSpinnerComponent);
|
|
276
|
+
this.overlay?.appendChild(this.spinnerInstance.location.nativeElement);
|
|
277
|
+
}
|
|
278
|
+
removeProgressSpinnerComponent() {
|
|
279
|
+
this.spinnerInstance?.destroy();
|
|
280
|
+
}
|
|
281
|
+
addOverlay() {
|
|
282
|
+
this.overlay = this.renderer.createElement('div');
|
|
283
|
+
this.renderer.setStyle(this.overlay, 'display', 'flex');
|
|
284
|
+
this.renderer.setStyle(this.overlay, 'justify-content', 'center');
|
|
285
|
+
this.renderer.setStyle(this.overlay, 'align-items', 'center');
|
|
286
|
+
this.renderer.setStyle(this.overlay, 'position', 'absolute');
|
|
287
|
+
this.renderer.setStyle(this.overlay, 'top', '0');
|
|
288
|
+
this.renderer.setStyle(this.overlay, 'left', '0');
|
|
289
|
+
this.renderer.setStyle(this.overlay, 'width', '100%');
|
|
290
|
+
this.renderer.setStyle(this.overlay, 'height', '100%');
|
|
291
|
+
this.renderer.appendChild(this.targetEl.nativeElement, this.overlay);
|
|
292
|
+
}
|
|
293
|
+
removeOverlay() {
|
|
294
|
+
if (this.overlay) {
|
|
295
|
+
this.renderer.removeChild(this.targetEl.nativeElement, this.overlay);
|
|
296
|
+
this.overlay = undefined;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
addBlurEffect() {
|
|
300
|
+
const style = this.renderer.createElement('style');
|
|
301
|
+
const blurRule = `
|
|
302
|
+
.ptr-loading-blur > *:not(:last-child) {
|
|
303
|
+
filter: blur(2px);
|
|
304
|
+
transition: filter 0.3s ease;
|
|
305
|
+
}
|
|
306
|
+
`;
|
|
307
|
+
this.renderer.appendChild(style, this.renderer.createText(blurRule));
|
|
308
|
+
this.renderer.appendChild(document.head, style);
|
|
309
|
+
this.renderer.addClass(this.targetEl.nativeElement, 'ptr-loading-blur');
|
|
310
|
+
}
|
|
311
|
+
removeBlurEffect() {
|
|
312
|
+
this.renderer.removeClass(this.targetEl.nativeElement, 'ptr-loading-blur');
|
|
313
|
+
}
|
|
314
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrLoadingSpinnerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
315
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.4", type: PtrLoadingSpinnerDirective, isStandalone: true, selector: "[ptrLoadingSpinner]", inputs: { ptrLoadingSpinner: "ptrLoadingSpinner" }, host: { properties: { "style.position": "this.hostPosition" } }, ngImport: i0 });
|
|
316
|
+
}
|
|
317
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrLoadingSpinnerDirective, decorators: [{
|
|
318
|
+
type: Directive,
|
|
319
|
+
args: [{
|
|
320
|
+
selector: '[ptrLoadingSpinner]',
|
|
321
|
+
standalone: true
|
|
322
|
+
}]
|
|
323
|
+
}], propDecorators: { hostPosition: [{
|
|
324
|
+
type: HostBinding,
|
|
325
|
+
args: ['style.position']
|
|
326
|
+
}], ptrLoadingSpinner: [{
|
|
327
|
+
type: Input,
|
|
328
|
+
args: [{ required: true }]
|
|
329
|
+
}] } });
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Optimized Async Loading Service using Angular Signals
|
|
333
|
+
* Supports global loading state and named loading areas with auto-cleanup
|
|
334
|
+
*
|
|
335
|
+
* To use as a non-singleton service, add to providers array in @Component decorator:
|
|
336
|
+
* @Component({
|
|
337
|
+
* selector: 'app-example',
|
|
338
|
+
* templateUrl: './example.component.html',
|
|
339
|
+
* providers: [PtrLoadingService]
|
|
340
|
+
* })
|
|
341
|
+
*
|
|
342
|
+
* Usage:
|
|
343
|
+
* Set loading: this.loadingService.setLoading(true)
|
|
344
|
+
* - Set loading: this.loadingService.setLoading(true, 'areaName')
|
|
345
|
+
*
|
|
346
|
+
* - Get loading (template): {{ loadingService.isLoading()() }}
|
|
347
|
+
* - Get loading (template): {{ loadingService.isLoading('areaName')() }}
|
|
348
|
+
*
|
|
349
|
+
* - Get loading (component): this.loadingService.isLoading()()
|
|
350
|
+
* - Get loading (component): this.loadingService.isLoading('areaName')()
|
|
351
|
+
*
|
|
352
|
+
* - React to loading changes: effect(() => console.log('Loading:', this.loadingService.isLoading('areaName')()))
|
|
353
|
+
*/
|
|
354
|
+
class PtrLoadingService {
|
|
355
|
+
globalTaskCount = signal(0);
|
|
356
|
+
loadingAreas = new Map();
|
|
357
|
+
isLoading(area) {
|
|
358
|
+
if (!area) {
|
|
359
|
+
return computed(() => this.globalTaskCount() > 0);
|
|
360
|
+
}
|
|
361
|
+
return computed(() => {
|
|
362
|
+
const areaSignal = this.loadingAreas.get(area);
|
|
363
|
+
return areaSignal ? areaSignal() > 0 : false;
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
setLoading(value, area) {
|
|
367
|
+
if (!area) {
|
|
368
|
+
this.updateTaskCount(this.globalTaskCount, value);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
this.updateNamedAreaLoading(area, value);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
resetLoading(area) {
|
|
375
|
+
if (!area) {
|
|
376
|
+
this.globalTaskCount.set(0);
|
|
377
|
+
}
|
|
378
|
+
else if (this.loadingAreas.has(area)) {
|
|
379
|
+
this.loadingAreas.get(area).set(0);
|
|
380
|
+
this.loadingAreas.delete(area);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
updateNamedAreaLoading(area, increment) {
|
|
384
|
+
let areaSignal = this.loadingAreas.get(area);
|
|
385
|
+
if (!areaSignal && increment) {
|
|
386
|
+
areaSignal = signal(0);
|
|
387
|
+
this.loadingAreas.set(area, areaSignal);
|
|
388
|
+
}
|
|
389
|
+
if (areaSignal) {
|
|
390
|
+
areaSignal.update(count => {
|
|
391
|
+
const newCount = increment ? count + 1 : Math.max(0, count - 1);
|
|
392
|
+
if (newCount === 0) {
|
|
393
|
+
this.loadingAreas.delete(area);
|
|
394
|
+
}
|
|
395
|
+
return newCount;
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
updateTaskCount(taskCount, increment) {
|
|
400
|
+
taskCount.update(count => increment ? count + 1 : Math.max(0, count - 1));
|
|
401
|
+
}
|
|
402
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrLoadingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
403
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrLoadingService, providedIn: 'root' });
|
|
404
|
+
}
|
|
405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrLoadingService, decorators: [{
|
|
406
|
+
type: Injectable,
|
|
407
|
+
args: [{
|
|
408
|
+
providedIn: 'root'
|
|
409
|
+
}]
|
|
410
|
+
}] });
|
|
411
|
+
|
|
412
|
+
class PtrDialogComponent {
|
|
413
|
+
dialogElement;
|
|
414
|
+
message = '';
|
|
415
|
+
buttonText = 'Confirm';
|
|
416
|
+
buttonStyle = 'normal';
|
|
417
|
+
closed = new EventEmitter();
|
|
418
|
+
ngAfterViewInit() {
|
|
419
|
+
this.dialogElement.nativeElement.showModal();
|
|
420
|
+
}
|
|
421
|
+
close() {
|
|
422
|
+
this.dialogElement.nativeElement.close();
|
|
423
|
+
}
|
|
424
|
+
confirm() {
|
|
425
|
+
this.closed.emit(true);
|
|
426
|
+
this.close();
|
|
427
|
+
}
|
|
428
|
+
onClose() {
|
|
429
|
+
this.closed.emit(null);
|
|
430
|
+
}
|
|
431
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
432
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.4", type: PtrDialogComponent, isStandalone: true, selector: "ptr-dialog", inputs: { message: "message", buttonText: "buttonText", buttonStyle: "buttonStyle" }, outputs: { closed: "closed" }, viewQueries: [{ propertyName: "dialogElement", first: true, predicate: ["dialogElement"], descendants: true }], ngImport: i0, template: "<dialog #dialogElement class=\"ptr-modal\" (close)=\"onClose()\">\r\n <div class=\"ptr-modal__content\">\r\n <button class=\"ptr-modal__close\" (click)=\"close()\" aria-label=\"Close dialog\">\r\n ×\r\n </button>\r\n <p>{{ message }}</p>\r\n <div class=\"ptr-modal__actions\">\r\n <ptr-button [buttonStyle]=\"buttonStyle\" (clicked)=\"confirm()\" [isSmallSize]=\"true\">{{buttonText}}</ptr-button>\r\n </div>\r\n </div>\r\n</dialog>", styles: [".ptr-modal{border-radius:var(--wp--custom--default-border-radius);border:none;padding:1rem}.ptr-modal__content{padding:1rem;position:relative}.ptr-modal__close{position:absolute;right:0;top:0;background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;line-height:1rem}.ptr-modal__actions{margin-top:20px;text-align:right}dialog.ptr-modal{opacity:0;transition:all .7s allow-discrete}dialog.ptr-modal[open]{opacity:1}dialog.ptr-modal::backdrop{background-color:#0000;transition:all .7s allow-discrete;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}dialog.ptr-modal[open]::backdrop{background-color:#0006}@starting-style{dialog[open]{opacity:0}}@starting-style{dialog[open]::backdrop{background-color:#0000}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: PtrButtonComponent, selector: "ptr-button", inputs: ["buttonStyle", "buttonType", "isDisabled", "hrefLink", "routerLinkValue", "extraClasses", "isSmallSize", "isIconButton"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
433
|
+
}
|
|
434
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrDialogComponent, decorators: [{
|
|
435
|
+
type: Component,
|
|
436
|
+
args: [{ selector: 'ptr-dialog', standalone: true, imports: [
|
|
437
|
+
CommonModule,
|
|
438
|
+
PtrButtonComponent
|
|
439
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<dialog #dialogElement class=\"ptr-modal\" (close)=\"onClose()\">\r\n <div class=\"ptr-modal__content\">\r\n <button class=\"ptr-modal__close\" (click)=\"close()\" aria-label=\"Close dialog\">\r\n ×\r\n </button>\r\n <p>{{ message }}</p>\r\n <div class=\"ptr-modal__actions\">\r\n <ptr-button [buttonStyle]=\"buttonStyle\" (clicked)=\"confirm()\" [isSmallSize]=\"true\">{{buttonText}}</ptr-button>\r\n </div>\r\n </div>\r\n</dialog>", styles: [".ptr-modal{border-radius:var(--wp--custom--default-border-radius);border:none;padding:1rem}.ptr-modal__content{padding:1rem;position:relative}.ptr-modal__close{position:absolute;right:0;top:0;background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;line-height:1rem}.ptr-modal__actions{margin-top:20px;text-align:right}dialog.ptr-modal{opacity:0;transition:all .7s allow-discrete}dialog.ptr-modal[open]{opacity:1}dialog.ptr-modal::backdrop{background-color:#0000;transition:all .7s allow-discrete;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}dialog.ptr-modal[open]::backdrop{background-color:#0006}@starting-style{dialog[open]{opacity:0}}@starting-style{dialog[open]::backdrop{background-color:#0000}}\n"] }]
|
|
440
|
+
}], propDecorators: { dialogElement: [{
|
|
441
|
+
type: ViewChild,
|
|
442
|
+
args: ['dialogElement']
|
|
443
|
+
}], message: [{
|
|
444
|
+
type: Input
|
|
445
|
+
}], buttonText: [{
|
|
446
|
+
type: Input
|
|
447
|
+
}], buttonStyle: [{
|
|
448
|
+
type: Input
|
|
449
|
+
}], closed: [{
|
|
450
|
+
type: Output
|
|
451
|
+
}] } });
|
|
452
|
+
|
|
453
|
+
class PtrDialogService {
|
|
454
|
+
appRef;
|
|
455
|
+
injector;
|
|
456
|
+
dialogComponentRef = null;
|
|
457
|
+
constructor(appRef, injector) {
|
|
458
|
+
this.appRef = appRef;
|
|
459
|
+
this.injector = injector;
|
|
460
|
+
}
|
|
461
|
+
open(options) {
|
|
462
|
+
const dialogResult$ = new Subject();
|
|
463
|
+
this.dialogComponentRef = createComponent(PtrDialogComponent, {
|
|
464
|
+
environmentInjector: this.injector,
|
|
465
|
+
});
|
|
466
|
+
const { instance } = this.dialogComponentRef;
|
|
467
|
+
instance.message = options.message;
|
|
468
|
+
instance.buttonText = options.buttonText || 'Confirm';
|
|
469
|
+
instance.buttonStyle = options.buttonStyle || 'normal';
|
|
470
|
+
instance.closed.subscribe((result) => {
|
|
471
|
+
this.removeDialog();
|
|
472
|
+
dialogResult$.next(result ?? false);
|
|
473
|
+
dialogResult$.complete();
|
|
474
|
+
});
|
|
475
|
+
document.body.appendChild(this.dialogComponentRef.location.nativeElement);
|
|
476
|
+
this.appRef.attachView(this.dialogComponentRef.hostView);
|
|
477
|
+
return dialogResult$.asObservable();
|
|
478
|
+
}
|
|
479
|
+
removeDialog() {
|
|
480
|
+
if (this.dialogComponentRef) {
|
|
481
|
+
this.appRef.detachView(this.dialogComponentRef.hostView);
|
|
482
|
+
this.dialogComponentRef.destroy();
|
|
483
|
+
this.dialogComponentRef = null;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrDialogService, deps: [{ token: i0.ApplicationRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
487
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrDialogService, providedIn: 'root' });
|
|
488
|
+
}
|
|
489
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrDialogService, decorators: [{
|
|
490
|
+
type: Injectable,
|
|
491
|
+
args: [{
|
|
492
|
+
providedIn: 'root'
|
|
493
|
+
}]
|
|
494
|
+
}], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }] });
|
|
495
|
+
|
|
496
|
+
class PtrTooltipComponent {
|
|
497
|
+
content = '';
|
|
498
|
+
tooltipDialog;
|
|
499
|
+
tooltipTimer;
|
|
500
|
+
showTooltip() {
|
|
501
|
+
clearTimeout(this.tooltipTimer);
|
|
502
|
+
this.tooltipTimer = setTimeout(() => {
|
|
503
|
+
this.tooltipDialog.nativeElement.show();
|
|
504
|
+
}, 200); // Small delay to prevent flickering on quick mouse movements
|
|
505
|
+
}
|
|
506
|
+
hideTooltip() {
|
|
507
|
+
clearTimeout(this.tooltipTimer);
|
|
508
|
+
this.tooltipTimer = setTimeout(() => {
|
|
509
|
+
this.tooltipDialog.nativeElement.close();
|
|
510
|
+
}, 200); // Small delay to allow moving mouse to tooltip
|
|
511
|
+
}
|
|
512
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
513
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.4", type: PtrTooltipComponent, isStandalone: true, selector: "ptr-tooltip", inputs: { content: "content" }, viewQueries: [{ propertyName: "tooltipDialog", first: true, predicate: ["tooltipDialog"], descendants: true }], ngImport: i0, template: "<span (mouseenter)=\"showTooltip()\" (mouseleave)=\"hideTooltip()\" class=\"tooltip-trigger\">\r\n <ng-content></ng-content>\r\n</span>\r\n<dialog #tooltipDialog class=\"ptr-tooltip\">\r\n <div class=\"ptr-tooltip__content\">{{ content }}</div>\r\n</dialog>", styles: [":host{display:inline-block;position:relative}.tooltip-trigger{cursor:help}.ptr-tooltip{position:absolute;bottom:100%;left:50%;transform:translate(-50%);border:none;border-radius:3px;padding:.5rem .75rem;background-color:#212121;border:0;color:#fff;font-size:.875rem;max-width:15.5rem;min-width:12.5rem;z-index:1000;margin:0 0 8px;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b}.ptr-tooltip:before{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #212121}.ptr-tooltip__content{white-space:pre-wrap;text-align:center;line-height:1.5}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
514
|
+
}
|
|
515
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: PtrTooltipComponent, decorators: [{
|
|
516
|
+
type: Component,
|
|
517
|
+
args: [{ selector: 'ptr-tooltip', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span (mouseenter)=\"showTooltip()\" (mouseleave)=\"hideTooltip()\" class=\"tooltip-trigger\">\r\n <ng-content></ng-content>\r\n</span>\r\n<dialog #tooltipDialog class=\"ptr-tooltip\">\r\n <div class=\"ptr-tooltip__content\">{{ content }}</div>\r\n</dialog>", styles: [":host{display:inline-block;position:relative}.tooltip-trigger{cursor:help}.ptr-tooltip{position:absolute;bottom:100%;left:50%;transform:translate(-50%);border:none;border-radius:3px;padding:.5rem .75rem;background-color:#212121;border:0;color:#fff;font-size:.875rem;max-width:15.5rem;min-width:12.5rem;z-index:1000;margin:0 0 8px;box-shadow:0 3px 6px #00000029,0 3px 6px #0000003b}.ptr-tooltip:before{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #212121}.ptr-tooltip__content{white-space:pre-wrap;text-align:center;line-height:1.5}\n"] }]
|
|
518
|
+
}], propDecorators: { content: [{
|
|
519
|
+
type: Input
|
|
520
|
+
}], tooltipDialog: [{
|
|
521
|
+
type: ViewChild,
|
|
522
|
+
args: ['tooltipDialog']
|
|
523
|
+
}] } });
|
|
524
|
+
|
|
138
525
|
/*
|
|
139
526
|
* Public API Surface of ngx-components
|
|
140
527
|
*/
|
|
141
|
-
// export { PtrTitleStrategy } from './lib/ptr-title/ptr-title-strategy';
|
|
142
528
|
|
|
143
529
|
/**
|
|
144
530
|
* Generated bundle index. Do not edit.
|
|
145
531
|
*/
|
|
146
532
|
|
|
147
|
-
export { PtrFormComponent, PtrMenuComponent, PtrTitleComponent };
|
|
533
|
+
export { PtrButtonComponent, PtrDialogComponent, PtrDialogService, PtrFormComponent, PtrLoadingService, PtrLoadingSpinnerComponent, PtrLoadingSpinnerDirective, PtrMenuComponent, PtrTitleComponent, PtrTooltipComponent };
|
|
148
534
|
//# sourceMappingURL=patter-ngx-components.mjs.map
|