@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 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 { Component } from '@angular/core';
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
- export class MenuComponent {
4
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", type: MenuComponent, isStandalone: true, selector: "ptr-menu", ngImport: i0, template: "<p>menu works!</p>\n", styles: [""] });
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: MenuComponent, decorators: [{
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: "<p>menu works!</p>\n" }]
10
- }] });
11
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9wYXR0ZXIvbmd4LWNvbXBvbmVudHMvc3JjL2xpYi9tZW51L21lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcGF0dGVyL25neC1jb21wb25lbnRzL3NyYy9saWIvbWVudS9tZW51LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBUzFDLE1BQU0sT0FBTyxhQUFhO3VHQUFiLGFBQWE7MkZBQWIsYUFBYSxvRUNUMUIsc0JBQ0E7OzJGRFFhLGFBQWE7a0JBUHpCLFNBQVM7K0JBQ0UsVUFBVSxjQUNSLElBQUksV0FDUCxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3B0ci1tZW51JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW10sXG4gIHRlbXBsYXRlVXJsOiAnLi9tZW51LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL21lbnUuY29tcG9uZW50LmNzcydcbn0pXG5leHBvcnQgY2xhc3MgTWVudUNvbXBvbmVudCB7XG5cbn1cbiIsIjxwPm1lbnUgd29ya3MhPC9wPlxuIl19
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=
@@ -2,4 +2,8 @@
2
2
  * Public API Surface of ngx-components
3
3
  */
4
4
  export * from './lib/menu/menu.component';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3BhdHRlci9uZ3gtY29tcG9uZW50cy9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsMkJBQTJCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIG5neC1jb21wb25lbnRzXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9saWIvbWVudS9tZW51LmNvbXBvbmVudCc7XG4iXX0=
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 MenuComponent {
5
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", type: MenuComponent, isStandalone: true, selector: "ptr-menu", ngImport: i0, template: "<p>menu works!</p>\n", styles: [""] });
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: MenuComponent, decorators: [{
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: "<p>menu works!</p>\n" }]
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 { MenuComponent };
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 declare class MenuComponent {
3
- static ɵfac: i0.ɵɵFactoryDeclaration<MenuComponent, never>;
4
- static ɵcmp: i0.ɵɵComponentDeclaration<MenuComponent, "ptr-menu", never, {}, {}, never, never, true, never>;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patter/ngx-components",
3
- "version": "0.0.1",
3
+ "version": "0.5.2",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^18.1.0",
6
6
  "@angular/core": "^18.1.0"
Binary file
package/public-api.d.ts CHANGED
@@ -1 +1,4 @@
1
1
  export * from './lib/menu/menu.component';
2
+ export * from './lib/forms/interfaces';
3
+ export { PtrFormComponent } from './lib/forms/form/form.component';
4
+ export { PtrTitleComponent } from './lib/ptr-title/ptr-title.component';
Binary file