@patter/ngx-components 0.0.1 → 0.5.2
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 +24 -24
- package/esm2022/lib/forms/form/form.component.mjs +86 -0
- package/esm2022/lib/forms/interfaces.mjs +2 -0
- package/esm2022/lib/menu/menu.component.mjs +15 -8
- package/esm2022/lib/ptr-title/ptr-title.component.mjs +42 -0
- package/esm2022/public-api.mjs +5 -1
- package/fesm2022/patter-ngx-components.mjs +133 -7
- package/fesm2022/patter-ngx-components.mjs.map +1 -1
- package/lib/forms/form/form.component.d.ts +28 -0
- package/lib/forms/interfaces.d.ts +27 -0
- package/lib/menu/menu.component.d.ts +9 -3
- package/lib/ptr-title/ptr-title.component.d.ts +14 -0
- package/package.json +1 -1
- package/patter-ngx-components-0.5.2.tgz +0 -0
- package/public-api.d.ts +3 -0
- package/patter-ngx-components-0.0.1.tgz +0 -0
package/README.md
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
# NgxComponents
|
|
2
|
-
|
|
3
|
-
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.1.0.
|
|
4
|
-
|
|
5
|
-
## Code scaffolding
|
|
6
|
-
|
|
7
|
-
Run `ng generate component component-name --project ngx-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-components`.
|
|
8
|
-
> Note: Don't forget to add `--project ngx-components` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
-
|
|
10
|
-
## Build
|
|
11
|
-
|
|
12
|
-
Run `ng build ngx-components` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
-
|
|
14
|
-
## Publishing
|
|
15
|
-
|
|
16
|
-
After building your library with `ng build ngx-components`, go to the dist folder `cd dist/ngx-components` and run `npm publish`.
|
|
17
|
-
|
|
18
|
-
## Running unit tests
|
|
19
|
-
|
|
20
|
-
Run `ng test ngx-components` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
-
|
|
22
|
-
## Further help
|
|
23
|
-
|
|
24
|
-
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
1
|
+
# NgxComponents
|
|
2
|
+
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.1.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Run `ng generate component component-name --project ngx-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-components`.
|
|
8
|
+
> Note: Don't forget to add `--project ngx-components` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
|
|
12
|
+
Run `ng build ngx-components` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
+
|
|
14
|
+
## Publishing
|
|
15
|
+
|
|
16
|
+
After building your library with `ng build ngx-components`, go to the dist folder `cd dist/ngx-components` and run `npm publish`.
|
|
17
|
+
|
|
18
|
+
## Running unit tests
|
|
19
|
+
|
|
20
|
+
Run `ng test ngx-components` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
+
|
|
22
|
+
## Further help
|
|
23
|
+
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, EventEmitter, inject, Input, Output } from '@angular/core';
|
|
3
|
+
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
|
|
4
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/common";
|
|
8
|
+
import * as i2 from "@angular/forms";
|
|
9
|
+
export class PtrFormComponent {
|
|
10
|
+
config;
|
|
11
|
+
loading = false;
|
|
12
|
+
error = null;
|
|
13
|
+
formSubmit = new EventEmitter();
|
|
14
|
+
formGroupCreated = new EventEmitter();
|
|
15
|
+
formGroup;
|
|
16
|
+
flatOptions = {};
|
|
17
|
+
groupedOptions = {};
|
|
18
|
+
fb = inject(FormBuilder);
|
|
19
|
+
cdr = inject(ChangeDetectorRef);
|
|
20
|
+
destroyRef = inject(DestroyRef);
|
|
21
|
+
ngOnInit() {
|
|
22
|
+
this.buildForm();
|
|
23
|
+
this.formGroupCreated.emit(this.formGroup);
|
|
24
|
+
this.config.fields.forEach(field => {
|
|
25
|
+
if (field.type === 'select' && field.options instanceof Observable) {
|
|
26
|
+
field.options
|
|
27
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
28
|
+
.subscribe(options => {
|
|
29
|
+
this.processOptions(field.name, options);
|
|
30
|
+
this.cdr.markForCheck(); // Trigger change detection after options are loaded
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else if (field.type === 'select' && Array.isArray(field.options)) {
|
|
34
|
+
this.processOptions(field.name, field.options);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
buildForm() {
|
|
39
|
+
const group = {};
|
|
40
|
+
this.config.fields.forEach(field => {
|
|
41
|
+
group[field.name] = [field.value || '', field.validators || []];
|
|
42
|
+
});
|
|
43
|
+
this.formGroup = this.fb.group(group);
|
|
44
|
+
}
|
|
45
|
+
onSubmit() {
|
|
46
|
+
if (this.formGroup.valid) {
|
|
47
|
+
this.formSubmit.emit(this.formGroup.value);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
resetForm() {
|
|
51
|
+
this.formGroup.reset();
|
|
52
|
+
this.config.fields.forEach(field => {
|
|
53
|
+
const control = this.formGroup.get(field.name);
|
|
54
|
+
control?.setValue(field.value || '', { emitEvent: false });
|
|
55
|
+
});
|
|
56
|
+
this.cdr.markForCheck();
|
|
57
|
+
}
|
|
58
|
+
processOptions(fieldName, options) {
|
|
59
|
+
if (options.length > 0 && 'options' in options[0]) {
|
|
60
|
+
this.groupedOptions[fieldName] = options;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
this.flatOptions[fieldName] = options;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
67
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", 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 <button type=\"submit\" [disabled]=\"loading || !formGroup.valid\">{{config.submitText}}</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.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
68
|
+
}
|
|
69
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrFormComponent, decorators: [{
|
|
70
|
+
type: Component,
|
|
71
|
+
args: [{ selector: 'ptr-form', standalone: true, imports: [
|
|
72
|
+
CommonModule,
|
|
73
|
+
ReactiveFormsModule
|
|
74
|
+
], 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 <button type=\"submit\" [disabled]=\"loading || !formGroup.valid\">{{config.submitText}}</button>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n" }]
|
|
75
|
+
}], propDecorators: { config: [{
|
|
76
|
+
type: Input
|
|
77
|
+
}], loading: [{
|
|
78
|
+
type: Input
|
|
79
|
+
}], error: [{
|
|
80
|
+
type: Input
|
|
81
|
+
}], formSubmit: [{
|
|
82
|
+
type: Output
|
|
83
|
+
}], formGroupCreated: [{
|
|
84
|
+
type: Output
|
|
85
|
+
}] } });
|
|
86
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9wYXR0ZXIvbmd4LWNvbXBvbmVudHMvc3JjL2xpYi9mb3Jtcy9mb3JtL2Zvcm0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcGF0dGVyL25neC1jb21wb25lbnRzL3NyYy9saWIvZm9ybXMvZm9ybS9mb3JtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFKLE9BQU8sRUFBRSxXQUFXLEVBQWEsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7O0FBWWxDLE1BQU0sT0FBTyxnQkFBZ0I7SUFFbEIsTUFBTSxDQUFpQjtJQUN2QixPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQ2hCLEtBQUssR0FBa0IsSUFBSSxDQUFDO0lBRTNCLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO0lBQ3JDLGdCQUFnQixHQUFHLElBQUksWUFBWSxFQUFhLENBQUM7SUFFM0QsU0FBUyxDQUFhO0lBQ3RCLFdBQVcsR0FBbUMsRUFBRSxDQUFDO0lBQ2pELGNBQWMsR0FBd0MsRUFBRSxDQUFDO0lBRXpELEVBQUUsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDekIsR0FBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lB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Q0gsQ0FBQzt1R0FsRVUsZ0JBQWdCOzJGQUFoQixnQkFBZ0IsbU5DakI3Qiwwd0hBK0VBLDJDRHBFSSxZQUFZLDJiQUNaLG1CQUFtQjs7MkZBS1YsZ0JBQWdCO2tCQVY1QixTQUFTOytCQUNFLFVBQVUsY0FDUixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixtQkFBbUI7cUJBQ3BCLG1CQUVnQix1QkFBdUIsQ0FBQyxNQUFNOzhCQUl0QyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFFSSxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBFdmVudEVtaXR0ZXIsIGluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgUHRyRm9ybUNvbmZpZywgUHRyT3B0aW9uLCBQdHJPcHRpb25Hcm91cCB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xyXG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncHRyLWZvcm0nLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgQ29tbW9uTW9kdWxlLFxyXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZVxyXG4gIF0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2Zvcm0uY29tcG9uZW50Lmh0bWwnLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQdHJGb3JtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuXHJcbiAgQElucHV0KCkgY29uZmlnITogUHRyRm9ybUNvbmZpZztcclxuICBASW5wdXQoKSBsb2FkaW5nID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZXJyb3I6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG5cclxuICBAT3V0cHV0KCkgZm9ybVN1Ym1pdCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gIEBPdXRwdXQoKSBmb3JtR3JvdXBDcmVhdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxGb3JtR3JvdXA+KCk7XHJcblxyXG4gIGZvcm1Hcm91cCE6IEZvcm1Hcm91cDtcclxuICBmbGF0T3B0aW9uczogeyBba2V5OiBzdHJpbmddOiBQdHJPcHRpb25bXSB9ID0ge307XHJcbiAgZ3JvdXBlZE9wdGlvbnM6IHsgW2tleTogc3RyaW5nXTogUHRyT3B0aW9uR3JvdXBbXSB9ID0ge307XHJcblxyXG4gIGZiID0gaW5qZWN0KEZvcm1CdWlsZGVyKTtcclxuICBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xyXG4gIGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZilcclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmJ1aWxkRm9ybSgpO1xyXG4gICAgdGhpcy5mb3JtR3JvdXBDcmVhdGVkLmVtaXQodGhpcy5mb3JtR3JvdXApO1xyXG5cclxuICAgIHRoaXMuY29uZmlnLmZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcclxuICAgICAgaWYgKGZpZWxkLnR5cGUgPT09ICdzZWxlY3QnICYmIGZpZWxkLm9wdGlvbnMgaW5zdGFuY2VvZiBPYnNlcnZhYmxlKSB7XHJcbiAgICAgICAgZmllbGQub3B0aW9uc1xyXG4gICAgICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXHJcbiAgICAgICAgICAuc3Vic2NyaWJlKG9wdGlvbnMgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NPcHRpb25zKGZpZWxkLm5hbWUsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTsgLy8gVHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIGFmdGVyIG9wdGlvbnMgYXJlIGxvYWRlZFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQudHlwZSA9PT0gJ3NlbGVjdCcgJiYgQXJyYXkuaXNBcnJheShmaWVsZC5vcHRpb25zKSkge1xyXG4gICAgICAgIHRoaXMucHJvY2Vzc09wdGlvbnMoZmllbGQubmFtZSwgZmllbGQub3B0aW9ucyk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgYnVpbGRGb3JtKCk6IHZvaWQge1xyXG4gICAgY29uc3QgZ3JvdXA6IGFueSA9IHt9O1xyXG4gICAgdGhpcy5jb25maWcuZmllbGRzLmZvckVhY2goZmllbGQgPT4ge1xyXG4gICAgICBncm91cFtmaWVsZC5uYW1lXSA9IFtmaWVsZC52YWx1ZSB8fCAnJywgZmllbGQudmFsaWRhdG9ycyB8fCBbXV07XHJcbiAgICB9KTtcclxuICAgIHRoaXMuZm9ybUdyb3VwID0gdGhpcy5mYi5ncm91cChncm91cCk7XHJcbiAgfVxyXG5cclxuICBvblN1Ym1pdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmZvcm1Hcm91cC52YWxpZCkge1xyXG4gICAgICB0aGlzLmZvcm1TdWJtaXQuZW1pdCh0aGlzLmZvcm1Hcm91cC52YWx1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcmVzZXRGb3JtKCk6IHZvaWQge1xyXG4gICAgdGhpcy5mb3JtR3JvdXAucmVzZXQoKTtcclxuICAgIHRoaXMuY29uZmlnLmZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcclxuICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybUdyb3VwLmdldChmaWVsZC5uYW1lKTtcclxuICAgICAgY29udHJvbD8uc2V0VmFsdWUoZmllbGQudmFsdWUgfHwgJycsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIHByaXZhdGUgcHJvY2Vzc09wdGlvbnMoZmllbGROYW1lOiBzdHJpbmcsIG9wdGlvbnM6IFB0ck9wdGlvbltdIHwgUHRyT3B0aW9uR3JvdXBbXSk6IHZvaWQge1xyXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCAmJiAnb3B0aW9ucycgaW4gb3B0aW9uc1swXSkge1xyXG4gICAgICB0aGlzLmdyb3VwZWRPcHRpb25zW2ZpZWxkTmFtZV0gPSBvcHRpb25zIGFzIFB0ck9wdGlvbkdyb3VwW107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZsYXRPcHRpb25zW2ZpZWxkTmFtZV0gPSBvcHRpb25zIGFzIFB0ck9wdGlvbltdO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IFtjbGFzc109XCInZ2Zvcm1fd3JhcHBlciAnICsgY29uZmlnLmZvcm1DbGFzc1wiPlxyXG5cclxuICA8ZGl2IGNsYXNzPVwiZ2Zvcm1fdmFsaWRhdGlvbl9lcnJvcnNcIiAqbmdJZj1cImVycm9yXCI+XHJcbiAgICA8aDIgY2xhc3M9XCJnZm9ybV9zdWJtaXNzaW9uX2Vycm9yIGhpZGVfc3VtbWFyeVwiPnt7ZXJyb3J9fTwvaDI+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgKm5nSWY9XCJjb25maWcudGl0bGVcIiBjbGFzcz1cImdmb3JtX2hlYWRpbmdcIj5cclxuICAgIDxoMiBjbGFzcz1cImdmb3JtX3RpdGxlXCI+e3sgY29uZmlnLnRpdGxlIH19PC9oMj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtR3JvdXBcIiAobmdTdWJtaXQpPVwib25TdWJtaXQoKVwiPlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJnZm9ybV9maWVsZHNcIj5cclxuXHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGNvbmZpZy5maWVsZHNcIj5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImdmaWVsZCBnZmllbGQtLXdpZHRoLXt7ZmllbGQuc2l6ZX19XCIgW2NsYXNzLmdmb3JtX2hpZGRlbl09XCJmaWVsZC50eXBlID09PSAnaGlkZGVuJ1wiXHJcbiAgICAgICAgICBbY2xhc3MuZ2ZpZWxkX2Vycm9yXT1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSk/LmludmFsaWQgJiYgZm9ybUdyb3VwLmdldChmaWVsZC5uYW1lKT8udG91Y2hlZFwiPlxyXG5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImdmaWVsZF9sYWJlbCBnZm9ybS1maWVsZC1sYWJlbFwiIFtmb3JdPVwiZmllbGQubmFtZVwiPnt7IGZpZWxkLmxhYmVsIH19PC9sYWJlbD5cclxuXHJcbiAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJmaWVsZC50eXBlXCI+XHJcblxyXG4gICAgICAgICAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIid0ZXh0J1wiIFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIHR5cGU9XCJ0ZXh0XCIgW2lkXT1cImZpZWxkLm5hbWVcIiAvPlxyXG5cclxuICAgICAgICAgICAgPHRleHRhcmVhICpuZ1N3aXRjaENhc2U9XCIndGV4dGFyZWEnXCIgW2lkXT1cImZpZWxkLm5hbWVcIiBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIj48L3RleHRhcmVhPlxyXG5cclxuICAgICAgICAgICAgPGlucHV0ICpuZ1N3aXRjaENhc2U9XCInZGF0ZSdcIiBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiB0eXBlPVwiZGF0ZVwiIFtpZF09XCJmaWVsZC5uYW1lXCIgLz5cclxuXHJcbiAgICAgICAgICAgIDxpbnB1dCAqbmdTd2l0Y2hDYXNlPVwiJ251bWJlcidcIiBbZm9ybUNvbnRyb2xOYW1lXT1cImZpZWxkLm5hbWVcIiB0eXBlPVwibnVtYmVyXCIgW2lkXT1cImZpZWxkLm5hbWVcIiAvPlxyXG5cclxuICAgICAgICAgICAgPGlucHV0ICpuZ1N3aXRjaENhc2U9XCInZW1haWwnXCIgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgdHlwZT1cImVtYWlsXCIgW2lkXT1cImZpZWxkLm5hbWVcIiAvPlxyXG5cclxuICAgICAgICAgICAgPGlucHV0ICpuZ1N3aXRjaENhc2U9XCIncGFzc3dvcmQnXCIgW2Zvcm1Db250cm9sTmFtZV09XCJmaWVsZC5uYW1lXCIgdHlwZT1cInBhc3N3b3JkXCIgW2lkXT1cImZpZWxkLm5hbWVcIiAvPlxyXG5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3NlbGVjdCdcIj5cclxuICAgICAgICAgICAgICA8c2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiZmllbGQubmFtZVwiIFtpZF09XCJmaWVsZC5uYW1lXCI+XHJcbiAgICAgICAgICAgICAgICA8IS0tIFJlbmRlciBncm91cGVkIG9wdGlvbnMgLS0+XHJcbiAgICAgICAgICAgICAgICA8b3B0Z3JvdXAgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGdyb3VwZWRPcHRpb25zW2ZpZWxkLm5hbWVdXCIgW2xhYmVsXT1cImdyb3VwLmdyb3VwTGFiZWxcIj5cclxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGdyb3VwLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgPC9vcHRncm91cD5cclxuICAgICAgICAgICAgICAgIDwhLS0gUmVuZGVyIGZsYXQgb3B0aW9ucyAtLT5cclxuICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBmbGF0T3B0aW9uc1tmaWVsZC5uYW1lXVwiIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cclxuICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cclxuICAgICAgICAgICAgICA8L3NlbGVjdD5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImdmaWVsZF9kZXNjcmlwdGlvbiB2YWxpZGF0aW9uX21lc3NhZ2UgZ2ZpZWxkX3ZhbGlkYXRpb25fbWVzc2FnZVwiXHJcbiAgICAgICAgICAgICpuZ0lmPVwiZm9ybUdyb3VwLmdldChmaWVsZC5uYW1lKT8uaW52YWxpZCAmJiBmb3JtR3JvdXAuZ2V0KGZpZWxkLm5hbWUpPy50b3VjaGVkXCI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmb3JtR3JvdXAuZ2V0KGZpZWxkLm5hbWUpPy5lcnJvcnM/LlsncmVxdWlyZWQnXVwiPlRoaXMgZmllbGQgaXMgcmVxdWlyZWQuPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmb3JtR3JvdXAuZ2V0KGZpZWxkLm5hbWUpPy5lcnJvcnM/LlsnZW1haWwnXVwiPlBsZWFzZSBlbnRlciBhIHZhbGlkIGVtYWlsXHJcbiAgICAgICAgICAgICAgYWRkcmVzcy48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSk/LmVycm9ycz8uWydtaW5sZW5ndGgnXVwiPlxyXG4gICAgICAgICAgICAgIE1pbmltdW0gbGVuZ3RoIGlzIHt7IGZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSk/LmVycm9ycz8uWydtaW5sZW5ndGgnXS5yZXF1aXJlZExlbmd0aCB9fSBjaGFyYWN0ZXJzLlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSk/LmVycm9ycz8uWydtYXhsZW5ndGgnXVwiPlxyXG4gICAgICAgICAgICAgIE1heGltdW0gbGVuZ3RoIGlzIHt7IGZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSk/LmVycm9ycz8uWydtYXhsZW5ndGgnXS5yZXF1aXJlZExlbmd0aCB9fSBjaGFyYWN0ZXJzLlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZvcm1Hcm91cC5nZXQoZmllbGQubmFtZSk/LmVycm9ycz8uWydwYXR0ZXJuJ11cIj5cclxuICAgICAgICAgICAgICBQbGVhc2UgbWF0Y2ggdGhlIHJlcXVpcmVkIGZvcm1hdC5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJnZm9ybV9mb290ZXJcIj5cclxuICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgW2Rpc2FibGVkXT1cImxvYWRpbmcgfHwgIWZvcm1Hcm91cC52YWxpZFwiPnt7Y29uZmlnLnN1Ym1pdFRleHR9fTwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gIDwvZm9ybT5cclxuPC9kaXY+XHJcbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3BhdHRlci9uZ3gtY29tcG9uZW50cy9zcmMvbGliL2Zvcm1zL2ludGVyZmFjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFzeW5jVmFsaWRhdG9yRm4sIFZhbGlkYXRvckZuIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tIFwicnhqc1wiO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBQdHJPcHRpb24ge1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbiAgdmFsdWU6IGFueTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBQdHJPcHRpb25Hcm91cCB7XHJcbiAgZ3JvdXBMYWJlbDogc3RyaW5nO1xyXG4gIG9wdGlvbnM6IFB0ck9wdGlvbltdO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFB0ckZvcm1GaWVsZCB7XHJcbiAgdHlwZTogJ3RleHQnIHwgJ3RleHRhcmVhJyB8ICdudW1iZXInIHwgJ2VtYWlsJyB8ICdwYXNzd29yZCcgfCAnc2VsZWN0JyB8ICdkYXRlJyB8ICdoaWRkZW4nO1xyXG4gIG5hbWU6IHN0cmluZztcclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIHZhbHVlPzogYW55O1xyXG4gIG9wdGlvbnM/OiBQdHJPcHRpb25bXSB8IFB0ck9wdGlvbkdyb3VwW10gfCBPYnNlcnZhYmxlPFB0ck9wdGlvbltdIHwgUHRyT3B0aW9uR3JvdXBbXT47XHJcbiAgc2l6ZT86ICdmdWxsJyB8ICdoYWxmJyB8ICd0aGlyZCc7XHJcbiAgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XHJcbiAgdmFsaWRhdG9ycz86IFZhbGlkYXRvckZuW107XHJcbiAgYXN5bmNWYWxpZGF0b3JzPzogQXN5bmNWYWxpZGF0b3JGbltdO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFB0ckZvcm1Db25maWcge1xyXG4gIHRpdGxlPzogc3RyaW5nO1xyXG4gIGZpZWxkczogUHRyRm9ybUZpZWxkW107XHJcbiAgZm9ybUNsYXNzPzogc3RyaW5nO1xyXG4gIHN1Ym1pdFRleHQ6IHN0cmluZztcclxufVxyXG4iXX0=
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
|
3
|
+
import { RouterModule } from '@angular/router';
|
|
2
4
|
import * as i0 from "@angular/core";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
import * as i1 from "@angular/common";
|
|
6
|
+
import * as i2 from "@angular/router";
|
|
7
|
+
export class PtrMenuComponent {
|
|
8
|
+
menuItems = [];
|
|
9
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", 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 });
|
|
6
11
|
}
|
|
7
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type:
|
|
12
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrMenuComponent, decorators: [{
|
|
8
13
|
type: Component,
|
|
9
|
-
args: [{ selector: 'ptr-menu', standalone: true, imports: [], template: "<
|
|
10
|
-
}]
|
|
11
|
-
|
|
14
|
+
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"] }]
|
|
15
|
+
}], propDecorators: { menuItems: [{
|
|
16
|
+
type: Input
|
|
17
|
+
}] } });
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9wYXR0ZXIvbmd4LWNvbXBvbmVudHMvc3JjL2xpYi9tZW51L21lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcGF0dGVyL25neC1jb21wb25lbnRzL3NyYy9saWIvbWVudS9tZW51LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7QUFnQi9DLE1BQU0sT0FBTyxnQkFBZ0I7SUFFbEIsU0FBUyxHQUFrQixFQUFFLENBQUM7dUdBRjVCLGdCQUFnQjsyRkFBaEIsZ0JBQWdCLHdHQ2xCN0IsdVRBUUEsb2xEREtZLFlBQVksMkpBQUUsWUFBWTs7MkZBS3pCLGdCQUFnQjtrQkFSNUIsU0FBUzsrQkFDRSxVQUFVLGNBQ1IsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxtQkFFcEIsdUJBQXVCLENBQUMsTUFBTTs4QkFLdEMsU0FBUztzQkFBakIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFJvdXRlck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFB0ck1lbnVJdGVtIHtcclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIGxpbms/OiBzdHJpbmc7XHJcbiAgY2hpbGRyZW4/OiBQdHJNZW51SXRlbVtdO1xyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3B0ci1tZW51JyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJvdXRlck1vZHVsZV0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL21lbnUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIHN0eWxlVXJsczogWycuL21lbnUuY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgUHRyTWVudUNvbXBvbmVudCB7XHJcblxyXG4gIEBJbnB1dCgpIG1lbnVJdGVtczogUHRyTWVudUl0ZW1bXSA9IFtdO1xyXG5cclxufVxyXG4iLCI8bmF2IGNsYXNzPVwicHRyLW1lbnVcIj5cclxuICA8dWwgY2xhc3M9XCJtZW51XCI+XHJcbiAgICA8bGkgY2xhc3M9XCJtZW51LWl0ZW1cIiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBtZW51SXRlbXNcIiByb3V0ZXJMaW5rQWN0aXZlPVwiY3VycmVudF9wYWdlX2l0ZW1cIlxyXG4gICAgICBbcm91dGVyTGlua0FjdGl2ZU9wdGlvbnNdPVwie2V4YWN0OiB0cnVlfVwiPlxyXG4gICAgICA8YSBbcm91dGVyTGlua109XCJpdGVtLmxpbmsgfHwgJyMnXCI+e3tpdGVtLmxhYmVsfX08L2E+XHJcbiAgICA8L2xpPlxyXG4gIDwvdWw+XHJcbjwvbmF2PlxyXG4iXX0=
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
3
|
+
import { ActivatedRoute, NavigationEnd, Router, TitleStrategy } from '@angular/router';
|
|
4
|
+
import { filter, map } from 'rxjs';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@angular/common";
|
|
7
|
+
export class PtrTitleComponent {
|
|
8
|
+
router = inject(Router);
|
|
9
|
+
activatedRoute = inject(ActivatedRoute);
|
|
10
|
+
titleStrategy = inject(TitleStrategy);
|
|
11
|
+
title$;
|
|
12
|
+
hideTitle$;
|
|
13
|
+
ngOnInit() {
|
|
14
|
+
const routeEvents$ = this.router.events.pipe(filter((event) => event instanceof NavigationEnd), map(() => this.getRoute(this.activatedRoute)));
|
|
15
|
+
this.hideTitle$ = routeEvents$.pipe(map(route => !!route.snapshot.data['hideTitle']));
|
|
16
|
+
this.title$ = routeEvents$.pipe(map(route => {
|
|
17
|
+
if (route.snapshot.data['hideTitle']) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
return this.titleStrategy.getResolvedTitleForRoute(route.snapshot) || '';
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
getRoute(route) {
|
|
24
|
+
while (route.firstChild) {
|
|
25
|
+
route = route.firstChild;
|
|
26
|
+
}
|
|
27
|
+
return route;
|
|
28
|
+
}
|
|
29
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
30
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", 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 });
|
|
31
|
+
}
|
|
32
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrTitleComponent, decorators: [{
|
|
33
|
+
type: Component,
|
|
34
|
+
args: [{
|
|
35
|
+
selector: 'ptr-title',
|
|
36
|
+
standalone: true,
|
|
37
|
+
imports: [CommonModule],
|
|
38
|
+
template: '<header class="entry-header is-layout-constrained my-3" *ngIf="!(hideTitle$ | async)"><h1 class="entry-title">{{ title$ | async }}</h1></header>',
|
|
39
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
40
|
+
}]
|
|
41
|
+
}] });
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHRyLXRpdGxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3BhdHRlci9uZ3gtY29tcG9uZW50cy9zcmMvbGliL3B0ci10aXRsZS9wdHItdGl0bGUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUVuRixPQUFPLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkYsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQWMsTUFBTSxNQUFNLENBQUM7OztBQVMvQyxNQUFNLE9BQU8saUJBQWlCO0lBRXBCLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDeEIsY0FBYyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN4QyxhQUFhLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRTlDLE1BQU0sQ0FBc0I7SUFDNUIsVUFBVSxDQUF1QjtJQUVqQyxRQUFRO1FBQ04sTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUMxQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQTBCLEVBQUUsQ0FBQyxLQUFLLFlBQVksYUFBYSxDQUFDLEVBQ3pFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUM5QyxDQUFDO1FBRUYsSUFBSSxDQUFDLFVBQVUsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUNqQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FDakQsQ0FBQztRQUVGLElBQUksQ0FBQyxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FDN0IsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ1YsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxPQUFPLEVBQUUsQ0FBQztZQUNaLENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMzRSxDQUFDLENBQUMsQ0FDSCxDQUFDO0lBRUosQ0FBQztJQUVPLFFBQVEsQ0FBQyxLQUFxQjtRQUNwQyxPQUFPLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN4QixLQUFLLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUMzQixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO3VHQW5DVSxpQkFBaUI7MkZBQWpCLGlCQUFpQixxRUFIbEIsa0pBQWtKLDJEQURsSixZQUFZOzsyRkFJWCxpQkFBaUI7a0JBUDdCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLFdBQVc7b0JBQ3JCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxZQUFZLENBQUM7b0JBQ3ZCLFFBQVEsRUFBRSxrSkFBa0o7b0JBQzVKLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2lCQUNoRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIGluamVjdCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFRpdGxlIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBOYXZpZ2F0aW9uRW5kLCBSb3V0ZXIsIFRpdGxlU3RyYXRlZ3kgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBmaWx0ZXIsIG1hcCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdwdHItdGl0bGUnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXHJcbiAgdGVtcGxhdGU6ICc8aGVhZGVyIGNsYXNzPVwiZW50cnktaGVhZGVyIGlzLWxheW91dC1jb25zdHJhaW5lZCBteS0zXCIgKm5nSWY9XCIhKGhpZGVUaXRsZSQgfCBhc3luYylcIj48aDEgY2xhc3M9XCJlbnRyeS10aXRsZVwiPnt7IHRpdGxlJCB8IGFzeW5jIH19PC9oMT48L2hlYWRlcj4nLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQdHJUaXRsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIHByaXZhdGUgcm91dGVyID0gaW5qZWN0KFJvdXRlcik7XHJcbiAgcHJpdmF0ZSBhY3RpdmF0ZWRSb3V0ZSA9IGluamVjdChBY3RpdmF0ZWRSb3V0ZSk7XHJcbiAgcHJpdmF0ZSB0aXRsZVN0cmF0ZWd5ID0gaW5qZWN0KFRpdGxlU3RyYXRlZ3kpO1xyXG5cclxuICB0aXRsZSQhOiBPYnNlcnZhYmxlPHN0cmluZz47XHJcbiAgaGlkZVRpdGxlJCE6IE9ic2VydmFibGU8Ym9vbGVhbj47XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgY29uc3Qgcm91dGVFdmVudHMkID0gdGhpcy5yb3V0ZXIuZXZlbnRzLnBpcGUoXHJcbiAgICAgIGZpbHRlcigoZXZlbnQpOiBldmVudCBpcyBOYXZpZ2F0aW9uRW5kID0+IGV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCksXHJcbiAgICAgIG1hcCgoKSA9PiB0aGlzLmdldFJvdXRlKHRoaXMuYWN0aXZhdGVkUm91dGUpKVxyXG4gICAgKTtcclxuXHJcbiAgICB0aGlzLmhpZGVUaXRsZSQgPSByb3V0ZUV2ZW50cyQucGlwZShcclxuICAgICAgbWFwKHJvdXRlID0+ICEhcm91dGUuc25hcHNob3QuZGF0YVsnaGlkZVRpdGxlJ10pXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMudGl0bGUkID0gcm91dGVFdmVudHMkLnBpcGUoXHJcbiAgICAgIG1hcChyb3V0ZSA9PiB7XHJcbiAgICAgICAgaWYgKHJvdXRlLnNuYXBzaG90LmRhdGFbJ2hpZGVUaXRsZSddKSB7XHJcbiAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLnRpdGxlU3RyYXRlZ3kuZ2V0UmVzb2x2ZWRUaXRsZUZvclJvdXRlKHJvdXRlLnNuYXBzaG90KSB8fCAnJztcclxuICAgICAgfSlcclxuICAgICk7XHJcblxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRSb3V0ZShyb3V0ZTogQWN0aXZhdGVkUm91dGUpOiBBY3RpdmF0ZWRSb3V0ZSB7XHJcbiAgICB3aGlsZSAocm91dGUuZmlyc3RDaGlsZCkge1xyXG4gICAgICByb3V0ZSA9IHJvdXRlLmZpcnN0Q2hpbGQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcm91dGU7XHJcbiAgfVxyXG5cclxufVxyXG4iXX0=
|
package/esm2022/public-api.mjs
CHANGED
|
@@ -2,4 +2,8 @@
|
|
|
2
2
|
* Public API Surface of ngx-components
|
|
3
3
|
*/
|
|
4
4
|
export * from './lib/menu/menu.component';
|
|
5
|
-
|
|
5
|
+
export * from './lib/forms/interfaces';
|
|
6
|
+
export { PtrFormComponent } from './lib/forms/form/form.component';
|
|
7
|
+
export { PtrTitleComponent } from './lib/ptr-title/ptr-title.component';
|
|
8
|
+
// export { PtrTitleStrategy } from './lib/ptr-title/ptr-title-strategy';
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3BhdHRlci9uZ3gtY29tcG9uZW50cy9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsMkJBQTJCLENBQUM7QUFFMUMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVuRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN4RSx5RUFBeUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2Ygbmd4LWNvbXBvbmVudHNcclxuICovXHJcblxyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9tZW51L21lbnUuY29tcG9uZW50JztcclxuXHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2Zvcm1zL2ludGVyZmFjZXMnO1xyXG5leHBvcnQgeyBQdHJGb3JtQ29tcG9uZW50IH0gZnJvbSAnLi9saWIvZm9ybXMvZm9ybS9mb3JtLmNvbXBvbmVudCc7XHJcblxyXG5leHBvcnQgeyBQdHJUaXRsZUNvbXBvbmVudCB9IGZyb20gJy4vbGliL3B0ci10aXRsZS9wdHItdGl0bGUuY29tcG9uZW50JztcclxuLy8gZXhwb3J0IHsgUHRyVGl0bGVTdHJhdGVneSB9IGZyb20gJy4vbGliL3B0ci10aXRsZS9wdHItdGl0bGUtc3RyYXRlZ3knOyJdfQ==
|
|
@@ -1,22 +1,148 @@
|
|
|
1
|
+
import * as i1 from '@angular/common';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
1
3
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
4
|
+
import { Component, ChangeDetectionStrategy, Input, EventEmitter, inject, ChangeDetectorRef, DestroyRef, Output } from '@angular/core';
|
|
5
|
+
import * as i2 from '@angular/router';
|
|
6
|
+
import { RouterModule, Router, ActivatedRoute, TitleStrategy, NavigationEnd } from '@angular/router';
|
|
7
|
+
import * as i2$1 from '@angular/forms';
|
|
8
|
+
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
|
|
9
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
10
|
+
import { Observable, filter, map } from 'rxjs';
|
|
3
11
|
|
|
4
|
-
class
|
|
5
|
-
|
|
6
|
-
static
|
|
12
|
+
class PtrMenuComponent {
|
|
13
|
+
menuItems = [];
|
|
14
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", 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 });
|
|
7
16
|
}
|
|
8
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type:
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrMenuComponent, decorators: [{
|
|
9
18
|
type: Component,
|
|
10
|
-
args: [{ selector: 'ptr-menu', standalone: true, imports: [], template: "<
|
|
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
|
+
}], propDecorators: { menuItems: [{
|
|
21
|
+
type: Input
|
|
22
|
+
}] } });
|
|
23
|
+
|
|
24
|
+
class PtrFormComponent {
|
|
25
|
+
config;
|
|
26
|
+
loading = false;
|
|
27
|
+
error = null;
|
|
28
|
+
formSubmit = new EventEmitter();
|
|
29
|
+
formGroupCreated = new EventEmitter();
|
|
30
|
+
formGroup;
|
|
31
|
+
flatOptions = {};
|
|
32
|
+
groupedOptions = {};
|
|
33
|
+
fb = inject(FormBuilder);
|
|
34
|
+
cdr = inject(ChangeDetectorRef);
|
|
35
|
+
destroyRef = inject(DestroyRef);
|
|
36
|
+
ngOnInit() {
|
|
37
|
+
this.buildForm();
|
|
38
|
+
this.formGroupCreated.emit(this.formGroup);
|
|
39
|
+
this.config.fields.forEach(field => {
|
|
40
|
+
if (field.type === 'select' && field.options instanceof Observable) {
|
|
41
|
+
field.options
|
|
42
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
43
|
+
.subscribe(options => {
|
|
44
|
+
this.processOptions(field.name, options);
|
|
45
|
+
this.cdr.markForCheck(); // Trigger change detection after options are loaded
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
else if (field.type === 'select' && Array.isArray(field.options)) {
|
|
49
|
+
this.processOptions(field.name, field.options);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
buildForm() {
|
|
54
|
+
const group = {};
|
|
55
|
+
this.config.fields.forEach(field => {
|
|
56
|
+
group[field.name] = [field.value || '', field.validators || []];
|
|
57
|
+
});
|
|
58
|
+
this.formGroup = this.fb.group(group);
|
|
59
|
+
}
|
|
60
|
+
onSubmit() {
|
|
61
|
+
if (this.formGroup.valid) {
|
|
62
|
+
this.formSubmit.emit(this.formGroup.value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
resetForm() {
|
|
66
|
+
this.formGroup.reset();
|
|
67
|
+
this.config.fields.forEach(field => {
|
|
68
|
+
const control = this.formGroup.get(field.name);
|
|
69
|
+
control?.setValue(field.value || '', { emitEvent: false });
|
|
70
|
+
});
|
|
71
|
+
this.cdr.markForCheck();
|
|
72
|
+
}
|
|
73
|
+
processOptions(fieldName, options) {
|
|
74
|
+
if (options.length > 0 && 'options' in options[0]) {
|
|
75
|
+
this.groupedOptions[fieldName] = options;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
this.flatOptions[fieldName] = options;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
82
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", 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 <button type=\"submit\" [disabled]=\"loading || !formGroup.valid\">{{config.submitText}}</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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
83
|
+
}
|
|
84
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrFormComponent, decorators: [{
|
|
85
|
+
type: Component,
|
|
86
|
+
args: [{ selector: 'ptr-form', standalone: true, imports: [
|
|
87
|
+
CommonModule,
|
|
88
|
+
ReactiveFormsModule
|
|
89
|
+
], 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 <button type=\"submit\" [disabled]=\"loading || !formGroup.valid\">{{config.submitText}}</button>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n" }]
|
|
90
|
+
}], propDecorators: { config: [{
|
|
91
|
+
type: Input
|
|
92
|
+
}], loading: [{
|
|
93
|
+
type: Input
|
|
94
|
+
}], error: [{
|
|
95
|
+
type: Input
|
|
96
|
+
}], formSubmit: [{
|
|
97
|
+
type: Output
|
|
98
|
+
}], formGroupCreated: [{
|
|
99
|
+
type: Output
|
|
100
|
+
}] } });
|
|
101
|
+
|
|
102
|
+
class PtrTitleComponent {
|
|
103
|
+
router = inject(Router);
|
|
104
|
+
activatedRoute = inject(ActivatedRoute);
|
|
105
|
+
titleStrategy = inject(TitleStrategy);
|
|
106
|
+
title$;
|
|
107
|
+
hideTitle$;
|
|
108
|
+
ngOnInit() {
|
|
109
|
+
const routeEvents$ = this.router.events.pipe(filter((event) => event instanceof NavigationEnd), map(() => this.getRoute(this.activatedRoute)));
|
|
110
|
+
this.hideTitle$ = routeEvents$.pipe(map(route => !!route.snapshot.data['hideTitle']));
|
|
111
|
+
this.title$ = routeEvents$.pipe(map(route => {
|
|
112
|
+
if (route.snapshot.data['hideTitle']) {
|
|
113
|
+
return '';
|
|
114
|
+
}
|
|
115
|
+
return this.titleStrategy.getResolvedTitleForRoute(route.snapshot) || '';
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
getRoute(route) {
|
|
119
|
+
while (route.firstChild) {
|
|
120
|
+
route = route.firstChild;
|
|
121
|
+
}
|
|
122
|
+
return route;
|
|
123
|
+
}
|
|
124
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
125
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", 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
|
+
}
|
|
127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: PtrTitleComponent, decorators: [{
|
|
128
|
+
type: Component,
|
|
129
|
+
args: [{
|
|
130
|
+
selector: 'ptr-title',
|
|
131
|
+
standalone: true,
|
|
132
|
+
imports: [CommonModule],
|
|
133
|
+
template: '<header class="entry-header is-layout-constrained my-3" *ngIf="!(hideTitle$ | async)"><h1 class="entry-title">{{ title$ | async }}</h1></header>',
|
|
134
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
135
|
+
}]
|
|
11
136
|
}] });
|
|
12
137
|
|
|
13
138
|
/*
|
|
14
139
|
* Public API Surface of ngx-components
|
|
15
140
|
*/
|
|
141
|
+
// export { PtrTitleStrategy } from './lib/ptr-title/ptr-title-strategy';
|
|
16
142
|
|
|
17
143
|
/**
|
|
18
144
|
* Generated bundle index. Do not edit.
|
|
19
145
|
*/
|
|
20
146
|
|
|
21
|
-
export {
|
|
147
|
+
export { PtrFormComponent, PtrMenuComponent, PtrTitleComponent };
|
|
22
148
|
//# sourceMappingURL=patter-ngx-components.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patter-ngx-components.mjs","sources":["../../../../projects/patter/ngx-components/src/lib/menu/menu.component.ts","../../../../projects/patter/ngx-components/src/lib/menu/menu.component.html","../../../../projects/patter/ngx-components/src/public-api.ts","../../../../projects/patter/ngx-components/src/patter-ngx-components.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'ptr-menu',\n standalone: true,\n imports: [],\n templateUrl: './menu.component.html',\n styleUrl: './menu.component.css'\n})\nexport class MenuComponent {\n\n}\n","<p>menu works!</p>\n","/*\n * Public API Surface of ngx-components\n */\n\nexport * from './lib/menu/menu.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;MASa,aAAa,CAAA;uGAAb,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,oECT1B,sBACA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;2FDQa,aAAa,EAAA,UAAA,EAAA,CAAA;kBAPzB,SAAS;+BACE,UAAU,EAAA,UAAA,EACR,IAAI,EAAA,OAAA,EACP,EAAE,EAAA,QAAA,EAAA,sBAAA,EAAA,CAAA;;;AELb;;AAEG;;ACFH;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"patter-ngx-components.mjs","sources":["../../../../projects/patter/ngx-components/src/lib/menu/menu.component.ts","../../../../projects/patter/ngx-components/src/lib/menu/menu.component.html","../../../../projects/patter/ngx-components/src/lib/forms/form/form.component.ts","../../../../projects/patter/ngx-components/src/lib/forms/form/form.component.html","../../../../projects/patter/ngx-components/src/lib/ptr-title/ptr-title.component.ts","../../../../projects/patter/ngx-components/src/public-api.ts","../../../../projects/patter/ngx-components/src/patter-ngx-components.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\r\nimport { RouterModule } from '@angular/router';\r\n\r\nexport interface PtrMenuItem {\r\n label: string;\r\n link?: string;\r\n children?: PtrMenuItem[];\r\n}\r\n\r\n@Component({\r\n selector: 'ptr-menu',\r\n standalone: true,\r\n imports: [CommonModule, RouterModule],\r\n templateUrl: './menu.component.html',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n styleUrls: ['./menu.component.scss']\r\n})\r\nexport class PtrMenuComponent {\r\n\r\n @Input() menuItems: PtrMenuItem[] = [];\r\n\r\n}\r\n","<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","import { CommonModule } from '@angular/common';\r\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core';\r\nimport { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { PtrFormConfig, PtrOption, PtrOptionGroup } from '../interfaces';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { Observable } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'ptr-form',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n ReactiveFormsModule\r\n ],\r\n templateUrl: './form.component.html',\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class PtrFormComponent implements OnInit {\r\n\r\n @Input() config!: PtrFormConfig;\r\n @Input() loading = false;\r\n @Input() error: string | null = null;\r\n\r\n @Output() formSubmit = new EventEmitter<any>();\r\n @Output() formGroupCreated = new EventEmitter<FormGroup>();\r\n\r\n formGroup!: FormGroup;\r\n flatOptions: { [key: string]: PtrOption[] } = {};\r\n groupedOptions: { [key: string]: PtrOptionGroup[] } = {};\r\n\r\n fb = inject(FormBuilder);\r\n cdr = inject(ChangeDetectorRef);\r\n destroyRef = inject(DestroyRef)\r\n\r\n ngOnInit(): void {\r\n this.buildForm();\r\n this.formGroupCreated.emit(this.formGroup);\r\n\r\n this.config.fields.forEach(field => {\r\n if (field.type === 'select' && field.options instanceof Observable) {\r\n field.options\r\n .pipe(takeUntilDestroyed(this.destroyRef))\r\n .subscribe(options => {\r\n this.processOptions(field.name, options);\r\n this.cdr.markForCheck(); // Trigger change detection after options are loaded\r\n });\r\n } else if (field.type === 'select' && Array.isArray(field.options)) {\r\n this.processOptions(field.name, field.options);\r\n }\r\n });\r\n }\r\n\r\n buildForm(): void {\r\n const group: any = {};\r\n this.config.fields.forEach(field => {\r\n group[field.name] = [field.value || '', field.validators || []];\r\n });\r\n this.formGroup = this.fb.group(group);\r\n }\r\n\r\n onSubmit(): void {\r\n if (this.formGroup.valid) {\r\n this.formSubmit.emit(this.formGroup.value);\r\n }\r\n }\r\n\r\n public resetForm(): void {\r\n this.formGroup.reset();\r\n this.config.fields.forEach(field => {\r\n const control = this.formGroup.get(field.name);\r\n control?.setValue(field.value || '', { emitEvent: false });\r\n });\r\n this.cdr.markForCheck();\r\n }\r\n\r\n\r\n\r\n private processOptions(fieldName: string, options: PtrOption[] | PtrOptionGroup[]): void {\r\n if (options.length > 0 && 'options' in options[0]) {\r\n this.groupedOptions[fieldName] = options as PtrOptionGroup[];\r\n } else {\r\n this.flatOptions[fieldName] = options as PtrOption[];\r\n }\r\n }\r\n}\r\n","<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 <button type=\"submit\" [disabled]=\"loading || !formGroup.valid\">{{config.submitText}}</button>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n","import { CommonModule } from '@angular/common';\r\nimport { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core';\r\nimport { Title } from '@angular/platform-browser';\r\nimport { ActivatedRoute, NavigationEnd, Router, TitleStrategy } from '@angular/router';\r\nimport { filter, map, Observable } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'ptr-title',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: '<header class=\"entry-header is-layout-constrained my-3\" *ngIf=\"!(hideTitle$ | async)\"><h1 class=\"entry-title\">{{ title$ | async }}</h1></header>',\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class PtrTitleComponent implements OnInit {\r\n\r\n private router = inject(Router);\r\n private activatedRoute = inject(ActivatedRoute);\r\n private titleStrategy = inject(TitleStrategy);\r\n\r\n title$!: Observable<string>;\r\n hideTitle$!: Observable<boolean>;\r\n\r\n ngOnInit() {\r\n const routeEvents$ = this.router.events.pipe(\r\n filter((event): event is NavigationEnd => event instanceof NavigationEnd),\r\n map(() => this.getRoute(this.activatedRoute))\r\n );\r\n\r\n this.hideTitle$ = routeEvents$.pipe(\r\n map(route => !!route.snapshot.data['hideTitle'])\r\n );\r\n\r\n this.title$ = routeEvents$.pipe(\r\n map(route => {\r\n if (route.snapshot.data['hideTitle']) {\r\n return '';\r\n }\r\n return this.titleStrategy.getResolvedTitleForRoute(route.snapshot) || '';\r\n })\r\n );\r\n\r\n }\r\n\r\n private getRoute(route: ActivatedRoute): ActivatedRoute {\r\n while (route.firstChild) {\r\n route = route.firstChild;\r\n }\r\n return route;\r\n }\r\n\r\n}\r\n","/*\r\n * Public API Surface of ngx-components\r\n */\r\n\r\nexport * from './lib/menu/menu.component';\r\n\r\nexport * from './lib/forms/interfaces';\r\nexport { PtrFormComponent } from './lib/forms/form/form.component';\r\n\r\nexport { PtrTitleComponent } from './lib/ptr-title/ptr-title.component';\r\n// export { PtrTitleStrategy } from './lib/ptr-title/ptr-title-strategy';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2"],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ChangeDetectorRef, DestroyRef, EventEmitter, OnInit } from '@angular/core';
|
|
2
|
+
import { FormBuilder, FormGroup } from '@angular/forms';
|
|
3
|
+
import { PtrFormConfig, PtrOption, PtrOptionGroup } from '../interfaces';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare class PtrFormComponent implements OnInit {
|
|
6
|
+
config: PtrFormConfig;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
error: string | null;
|
|
9
|
+
formSubmit: EventEmitter<any>;
|
|
10
|
+
formGroupCreated: EventEmitter<FormGroup<any>>;
|
|
11
|
+
formGroup: FormGroup;
|
|
12
|
+
flatOptions: {
|
|
13
|
+
[key: string]: PtrOption[];
|
|
14
|
+
};
|
|
15
|
+
groupedOptions: {
|
|
16
|
+
[key: string]: PtrOptionGroup[];
|
|
17
|
+
};
|
|
18
|
+
fb: FormBuilder;
|
|
19
|
+
cdr: ChangeDetectorRef;
|
|
20
|
+
destroyRef: DestroyRef;
|
|
21
|
+
ngOnInit(): void;
|
|
22
|
+
buildForm(): void;
|
|
23
|
+
onSubmit(): void;
|
|
24
|
+
resetForm(): void;
|
|
25
|
+
private processOptions;
|
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PtrFormComponent, never>;
|
|
27
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PtrFormComponent, "ptr-form", never, { "config": { "alias": "config"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "error": { "alias": "error"; "required": false; }; }, { "formSubmit": "formSubmit"; "formGroupCreated": "formGroupCreated"; }, never, never, true, never>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AsyncValidatorFn, ValidatorFn } from "@angular/forms";
|
|
2
|
+
import { Observable } from "rxjs";
|
|
3
|
+
export interface PtrOption {
|
|
4
|
+
label: string;
|
|
5
|
+
value: any;
|
|
6
|
+
}
|
|
7
|
+
export interface PtrOptionGroup {
|
|
8
|
+
groupLabel: string;
|
|
9
|
+
options: PtrOption[];
|
|
10
|
+
}
|
|
11
|
+
export interface PtrFormField {
|
|
12
|
+
type: 'text' | 'textarea' | 'number' | 'email' | 'password' | 'select' | 'date' | 'hidden';
|
|
13
|
+
name: string;
|
|
14
|
+
label: string;
|
|
15
|
+
value?: any;
|
|
16
|
+
options?: PtrOption[] | PtrOptionGroup[] | Observable<PtrOption[] | PtrOptionGroup[]>;
|
|
17
|
+
size?: 'full' | 'half' | 'third';
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
validators?: ValidatorFn[];
|
|
20
|
+
asyncValidators?: AsyncValidatorFn[];
|
|
21
|
+
}
|
|
22
|
+
export interface PtrFormConfig {
|
|
23
|
+
title?: string;
|
|
24
|
+
fields: PtrFormField[];
|
|
25
|
+
formClass?: string;
|
|
26
|
+
submitText: string;
|
|
27
|
+
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export interface PtrMenuItem {
|
|
3
|
+
label: string;
|
|
4
|
+
link?: string;
|
|
5
|
+
children?: PtrMenuItem[];
|
|
6
|
+
}
|
|
7
|
+
export declare class PtrMenuComponent {
|
|
8
|
+
menuItems: PtrMenuItem[];
|
|
9
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PtrMenuComponent, never>;
|
|
10
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PtrMenuComponent, "ptr-menu", never, { "menuItems": { "alias": "menuItems"; "required": false; }; }, {}, never, never, true, never>;
|
|
5
11
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class PtrTitleComponent implements OnInit {
|
|
5
|
+
private router;
|
|
6
|
+
private activatedRoute;
|
|
7
|
+
private titleStrategy;
|
|
8
|
+
title$: Observable<string>;
|
|
9
|
+
hideTitle$: Observable<boolean>;
|
|
10
|
+
ngOnInit(): void;
|
|
11
|
+
private getRoute;
|
|
12
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PtrTitleComponent, never>;
|
|
13
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PtrTitleComponent, "ptr-title", never, {}, {}, never, never, true, never>;
|
|
14
|
+
}
|
package/package.json
CHANGED
|
Binary file
|
package/public-api.d.ts
CHANGED
|
Binary file
|