@tehw0lf/contact-form 0.14.4 → 0.17.5

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.
Files changed (48) hide show
  1. package/README.md +46 -46
  2. package/esm2022/index.mjs +2 -0
  3. package/esm2022/lib/contact-form/contact-form.component.mjs +115 -0
  4. package/fesm2022/tehw0lf-contact-form.mjs +122 -0
  5. package/fesm2022/tehw0lf-contact-form.mjs.map +1 -0
  6. package/index.d.ts +0 -1
  7. package/lib/contact-form/contact-form.component.d.ts +28 -20
  8. package/package.json +15 -25
  9. package/esm2020/index.mjs +0 -3
  10. package/esm2020/lib/contact-form/contact-form.component.mjs +0 -97
  11. package/esm2020/lib/contact-form.module.mjs +0 -42
  12. package/esm2020/lib/email-api.service.mjs +0 -32
  13. package/fesm2015/tehw0lf-contact-form.mjs +0 -166
  14. package/fesm2015/tehw0lf-contact-form.mjs.map +0 -1
  15. package/fesm2020/tehw0lf-contact-form.mjs +0 -166
  16. package/fesm2020/tehw0lf-contact-form.mjs.map +0 -1
  17. package/lib/contact-form.module.d.ts +0 -13
  18. package/lib/email-api.service.d.ts +0 -13
  19. package/schematics/collection.json +0 -16
  20. package/schematics/ng-add/index.d.ts +0 -3
  21. package/schematics/ng-add/index.js +0 -46
  22. package/schematics/ng-add/index.js.map +0 -1
  23. package/schematics/ng-add/index.spec.d.ts +0 -1
  24. package/schematics/ng-add/index.spec.js +0 -102
  25. package/schematics/ng-add/index.spec.js.map +0 -1
  26. package/schematics/ng-add/package-config.d.ts +0 -12
  27. package/schematics/ng-add/package-config.js +0 -48
  28. package/schematics/ng-add/package-config.js.map +0 -1
  29. package/schematics/ng-add/schema.d.ts +0 -3
  30. package/schematics/ng-add/schema.js +0 -3
  31. package/schematics/ng-add/schema.js.map +0 -1
  32. package/schematics/ng-add/schema.json +0 -16
  33. package/schematics/ng-add/setup.d.ts +0 -3
  34. package/schematics/ng-add/setup.js +0 -50
  35. package/schematics/ng-add/setup.js.map +0 -1
  36. package/schematics/testing/file-content.d.ts +0 -10
  37. package/schematics/testing/file-content.js +0 -13
  38. package/schematics/testing/file-content.js.map +0 -1
  39. package/schematics/testing/test-app.d.ts +0 -12
  40. package/schematics/testing/test-app.js +0 -44
  41. package/schematics/testing/test-app.js.map +0 -1
  42. package/schematics/testing/test-library.d.ts +0 -11
  43. package/schematics/testing/test-library.js +0 -21
  44. package/schematics/testing/test-library.js.map +0 -1
  45. package/schematics/testing/test-project.d.ts +0 -11
  46. package/schematics/testing/test-project.js +0 -29
  47. package/schematics/testing/test-project.js.map +0 -1
  48. /package/{esm2020 → esm2022}/tehw0lf-contact-form.mjs +0 -0
package/README.md CHANGED
@@ -1,9 +1,6 @@
1
1
  # contact-form
2
2
 
3
3
  This provides a simple way to let your users contact you.
4
- The component takes as input an API-URL.
5
-
6
- Default is 'https://forwardmethis.com/tehwolf@pm.me' - please change it, as you will need to confirm the API access for the first email you will receive.
7
4
 
8
5
  ## Installation
9
6
 
@@ -13,12 +10,12 @@ The following dependencies are needed:
13
10
 
14
11
  ```bash
15
12
  @angular/animations
16
- @angular/cdk
17
13
  @angular/common
18
14
  @angular/core
19
- @angular/flex-layout
20
15
  @angular/forms
21
- @angular/material
16
+ @ngx-formly/core
17
+ @ngx-formly/material
18
+ @tehw0lf/mvc
22
19
  ```
23
20
 
24
21
  ### Module
@@ -28,37 +25,64 @@ Run `ng add @tehw0lf/contact-form` in the workspace root of your angular applica
28
25
 
29
26
  ## Usage
30
27
 
31
- The contact form component takes an apiURL and an email as input. By default, this is set to [ForwardMeThis](https://forwardmethis.com) and the email address is blank. You can set the variables on the component tag:
28
+ The contact form component takes an apiCallback returning a boolean Observable as mandatory input. By default, this is set to a dummy function that returns true if the form's value contains a name and false if not. A more verbose error message can be provided by updating sendErrorMessage with the error message dynamically from the callback.
29
+
30
+ A form can be generated from an arbitrary model. By default, the form contains name, email and message fields.
32
31
 
33
32
  ```html
34
- <contact-form
35
- [apiURL]="emailBackendURL"
36
- [email]="yourEmailAddress"
37
- ></contact-form>
33
+ <contact-form [apiCallback]="apiCallback"></contact-form>
38
34
  ```
39
35
 
40
- In your component, set the `emailBackendURL` and `yourEmailAddress` properties. The naming of these variables is arbitrary:
36
+ In your component, set the `apiCallback` property. The naming of these variables is arbitrary:
41
37
 
42
38
  ```ts
43
- emailBackendURL; //'https://forwardmethis.com/';
44
- yourEmailAddress; //'my@mail.com'; //this is optional, if your API URL doesn't require an email address parameter
39
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+ apiCallback = (formValue: any) => {
41
+ // run logic and send to api, return true on success and false on failure
42
+ // update sendErrorText input with error text for more verbose error message
43
+ if (formValue.name) {
44
+ return of(true);
45
+ } else {
46
+ return of(false);
47
+ }
48
+ };
45
49
  ```
46
50
 
47
- This contact form will send a POST request to the API, containing the following data structure:
51
+ On submitting the form, your API callback will be executed. The status will be reflected by a message that can be overridden by setting `sendErrorText` and `sendSuccessfulText`.
52
+
53
+ ## Form Generation
54
+
55
+ In order to generate the form, a config array can be provided. By default, the config array contains name, email and message fields without default values.
48
56
 
49
- ```json
50
- {
51
- "name": "your entered name",
52
- "email": "your entered email address",
53
- "message": "your entered message"
57
+ ```ts
58
+ interface FormConfigEntry {
59
+ field: string;
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ value?: any;
62
+ required?: boolean;
63
+ type?: string;
54
64
  }
65
+
66
+ formConfig: FormConfigEntry[] = [
67
+ { field: 'name', required: true },
68
+ { field: 'email', required: true },
69
+ { field: 'message', required: true, type: 'textarea' }
70
+ ];
55
71
  ```
56
72
 
57
- You can of course use your own backend with this data structure, as the API-URL and E-Mail address can be overridden as shown above.
73
+ ## Text
74
+
75
+ The message texts can optionally be specified.
76
+
77
+ ```ts
78
+ sendSuccessfulText; //'E-Mail successfully sent';
79
+
80
+ sendErrorText; //'Send error';
81
+ ```
58
82
 
59
83
  ## Theming
60
84
 
61
- The styles of form background, button, input and text can be customized with optional input parameters:
85
+ The styles of form background, button and text can be customized with optional input parameters:
62
86
 
63
87
  ```ts
64
88
  buttonStyle; /* {
@@ -74,33 +98,9 @@ formStyle; /* {
74
98
  'box-shadow': '0 2px 10px rgba(0, 0, 0, 0.075)'
75
99
  }*/
76
100
 
77
- inputStyle; /* {
78
- border: 'none',
79
- color: '#282b2e',
80
- 'background-color': '#fff'
81
- }*/
82
-
83
101
  textStyle; //{ color: '#cc7832' };
84
102
  ```
85
103
 
86
- ## Text
87
-
88
- You can specify your own texts for the fields and labels, or leave the default English version
89
-
90
- ```ts
91
- nameLabel; //'Your Name';
92
-
93
- emailAddressLabel; //'Your E-Mail Address';
94
-
95
- messageLabel; //'Your Message';
96
-
97
- sendText; //'Send';
98
-
99
- sendSuccessfulText; //'E-Mail successfully sent';
100
-
101
- sendErrorText; //'Send error';
102
- ```
103
-
104
104
  ## Development
105
105
 
106
106
  ### Serve
@@ -0,0 +1,2 @@
1
+ export * from './lib/contact-form/contact-form.component';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzL2NvbnRhY3QtZm9ybS9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywyQ0FBMkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRhY3QtZm9ybS9jb250YWN0LWZvcm0uY29tcG9uZW50JztcbiJdfQ==
@@ -0,0 +1,115 @@
1
+ import { LayoutModule } from '@angular/cdk/layout';
2
+ import { AsyncPipe, NgStyle } from '@angular/common';
3
+ import { Component, Input, ViewEncapsulation } from '@angular/core';
4
+ import { FormGroup, ReactiveFormsModule } from '@angular/forms';
5
+ import { FormlyModule } from '@ngx-formly/core';
6
+ import { FormlyMaterialModule } from '@ngx-formly/material';
7
+ import { Subject } from 'rxjs';
8
+ import { takeUntil, tap } from 'rxjs/operators';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "@angular/forms";
11
+ import * as i2 from "@ngx-formly/core";
12
+ export class ContactFormComponent {
13
+ constructor() {
14
+ this.buttonStyle = {
15
+ 'background-color': '#333333',
16
+ border: 'none',
17
+ color: '#cc7832'
18
+ };
19
+ this.formStyle = {
20
+ color: '#437da8',
21
+ 'background-color': 'rgba(34, 34, 34, 0.75)',
22
+ 'backdrop-filter': 'blur(50px)',
23
+ 'box-shadow': '0 2px 10px rgba(0, 0, 0, 0.075)'
24
+ };
25
+ this.textStyle = { color: '#cc7832' };
26
+ this.sendText = 'Send';
27
+ this.sendSuccessfulText = 'E-Mail successfully sent';
28
+ this.sendErrorText = 'Send error';
29
+ this.formConfig = [
30
+ { field: 'name', required: true },
31
+ { field: 'email', required: true },
32
+ { field: 'message', required: true, type: 'textarea' }
33
+ ];
34
+ this.form = new FormGroup({});
35
+ this.fields = [];
36
+ this.model = {};
37
+ this.emailSent = new Subject();
38
+ this.emailSent$ = this.emailSent.asObservable();
39
+ this.unsubscribe$ = new Subject();
40
+ this.emailSent.next(null);
41
+ }
42
+ ngOnInit() {
43
+ this.buildConfig();
44
+ }
45
+ ngOnDestroy() {
46
+ this.unsubscribe$.next();
47
+ this.unsubscribe$.complete();
48
+ }
49
+ submitFormData(formData) {
50
+ this.apiCallback(formData)
51
+ .pipe(tap((success) => this.emailSent.next(success)), takeUntil(this.unsubscribe$))
52
+ .subscribe();
53
+ }
54
+ buildConfig() {
55
+ this.formConfig.forEach((entry) => {
56
+ if (entry.value) {
57
+ this.model[entry.field] = entry.value;
58
+ }
59
+ this.fields.push({
60
+ key: entry.field,
61
+ type: entry.type ? entry.type : 'input',
62
+ props: {
63
+ label: entry.field.toLocaleUpperCase(),
64
+ placeholder: 'Enter ' + entry.field,
65
+ required: true,
66
+ attributes: { style: this.flattenStyle(this.textStyle) }
67
+ },
68
+ templateOptions: entry.type === 'textarea'
69
+ ? {
70
+ autosize: true,
71
+ minRows: 5,
72
+ maxRows: 10
73
+ }
74
+ : {}
75
+ });
76
+ });
77
+ }
78
+ flattenStyle(styleObject) {
79
+ return Object.entries(styleObject)
80
+ .flatMap((entry) => {
81
+ return `${entry[0]}: ${entry[1]};`;
82
+ })
83
+ .join('');
84
+ }
85
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: ContactFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
86
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.3", type: ContactFormComponent, isStandalone: true, selector: "contact-form", inputs: { buttonStyle: "buttonStyle", formStyle: "formStyle", textStyle: "textStyle", sendText: "sendText", sendSuccessfulText: "sendSuccessfulText", sendErrorText: "sendErrorText", formConfig: "formConfig", apiCallback: "apiCallback" }, ngImport: i0, template: "<form\n [ngStyle]=\"formStyle\"\n class=\"contact-form flex-column flex-fxflex\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submitFormData(model)\"\n>\n <formly-form [form]=\"form\" [fields]=\"fields\" [model]=\"model\"></formly-form>\n <button\n [ngStyle]=\"buttonStyle\"\n class=\"form-button\"\n type=\"submit\"\n [disabled]=\"!form.valid\"\n >\n {{ sendText }}\n </button>\n <div [ngStyle]=\"textStyle\" class=\"form-status\">\n @if ((emailSent$ | async) === true) {\n {{ sendSuccessfulText }}\n } @else if ((emailSent$ | async) === false) {\n {{ sendErrorText }}\n }\n </div>\n</form>\n", styles: [".contact-form{max-width:500px;margin:auto;padding:40px 40px 30px;box-sizing:border-box}.form-button{margin-top:.33rem;display:block;border-radius:.25rem;height:36px;width:100%;padding:.375rem .75rem}.form-status{height:19px;margin-top:1rem}.flex-align-start{justify-content:flex-start}.flex-align-stretch{align-content:stretch;align-items:stretch}.flex-column{display:flex;flex-direction:column;box-sizing:border-box}.flex-row{display:flex;flex-direction:row;box-sizing:border-box}.flex-row-wrap{display:flex;flex-direction:row;flex-wrap:wrap;box-sizing:border-box}.flex-fxflex{flex:1 1 0%}.flex-fxflex-responsive{flex:0 1 calc(33.3% - 32px)}.flex-fxflex-lt-md{flex:0 1 calc(50% - 32px)}.flex-fxflex-lt-sm{flex:100%}.flex-fxflex-fill{height:100%;min-height:100%;min-width:100%;width:100%}.flex-gap-5{margin-right:5px}.flex-gap-12{margin-right:12px}.flex-gap-20{margin-right:20px}\n"], dependencies: [{ kind: "ngmodule", type: LayoutModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i2.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: FormlyMaterialModule }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
87
+ }
88
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: ContactFormComponent, decorators: [{
89
+ type: Component,
90
+ args: [{ selector: 'contact-form', encapsulation: ViewEncapsulation.None, standalone: true, imports: [
91
+ LayoutModule,
92
+ ReactiveFormsModule,
93
+ FormlyModule,
94
+ FormlyMaterialModule,
95
+ NgStyle,
96
+ AsyncPipe
97
+ ], template: "<form\n [ngStyle]=\"formStyle\"\n class=\"contact-form flex-column flex-fxflex\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submitFormData(model)\"\n>\n <formly-form [form]=\"form\" [fields]=\"fields\" [model]=\"model\"></formly-form>\n <button\n [ngStyle]=\"buttonStyle\"\n class=\"form-button\"\n type=\"submit\"\n [disabled]=\"!form.valid\"\n >\n {{ sendText }}\n </button>\n <div [ngStyle]=\"textStyle\" class=\"form-status\">\n @if ((emailSent$ | async) === true) {\n {{ sendSuccessfulText }}\n } @else if ((emailSent$ | async) === false) {\n {{ sendErrorText }}\n }\n </div>\n</form>\n", styles: [".contact-form{max-width:500px;margin:auto;padding:40px 40px 30px;box-sizing:border-box}.form-button{margin-top:.33rem;display:block;border-radius:.25rem;height:36px;width:100%;padding:.375rem .75rem}.form-status{height:19px;margin-top:1rem}.flex-align-start{justify-content:flex-start}.flex-align-stretch{align-content:stretch;align-items:stretch}.flex-column{display:flex;flex-direction:column;box-sizing:border-box}.flex-row{display:flex;flex-direction:row;box-sizing:border-box}.flex-row-wrap{display:flex;flex-direction:row;flex-wrap:wrap;box-sizing:border-box}.flex-fxflex{flex:1 1 0%}.flex-fxflex-responsive{flex:0 1 calc(33.3% - 32px)}.flex-fxflex-lt-md{flex:0 1 calc(50% - 32px)}.flex-fxflex-lt-sm{flex:100%}.flex-fxflex-fill{height:100%;min-height:100%;min-width:100%;width:100%}.flex-gap-5{margin-right:5px}.flex-gap-12{margin-right:12px}.flex-gap-20{margin-right:20px}\n"] }]
98
+ }], ctorParameters: () => [], propDecorators: { buttonStyle: [{
99
+ type: Input
100
+ }], formStyle: [{
101
+ type: Input
102
+ }], textStyle: [{
103
+ type: Input
104
+ }], sendText: [{
105
+ type: Input
106
+ }], sendSuccessfulText: [{
107
+ type: Input
108
+ }], sendErrorText: [{
109
+ type: Input
110
+ }], formConfig: [{
111
+ type: Input
112
+ }], apiCallback: [{
113
+ type: Input
114
+ }] } });
115
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFjdC1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29udGFjdC1mb3JtL3NyYy9saWIvY29udGFjdC1mb3JtL2NvbnRhY3QtZm9ybS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbnRhY3QtZm9ybS9zcmMvbGliL2NvbnRhY3QtZm9ybS9jb250YWN0LWZvcm0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDckQsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBR0wsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRSxPQUFPLEVBQXFCLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQTBCaEQsTUFBTSxPQUFPLG9CQUFvQjtJQXdDL0I7UUF2Q1MsZ0JBQVcsR0FBRztZQUNyQixrQkFBa0IsRUFBRSxTQUFTO1lBQzdCLE1BQU0sRUFBRSxNQUFNO1lBQ2QsS0FBSyxFQUFFLFNBQVM7U0FDakIsQ0FBQztRQUVPLGNBQVMsR0FBRztZQUNuQixLQUFLLEVBQUUsU0FBUztZQUNoQixrQkFBa0IsRUFBRSx3QkFBd0I7WUFDNUMsaUJBQWlCLEVBQUUsWUFBWTtZQUMvQixZQUFZLEVBQUUsaUNBQWlD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QUFXLENBQUM7YUFDL0IsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDakIsT0FBTyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUNyQyxDQUFDLENBQUM7YUFDRCxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDZCxDQUFDOzhHQS9GVSxvQkFBb0I7a0dBQXBCLG9CQUFvQixzVEN2Q2pDLHduQkF1QkEsMDZCRFFJLFlBQVksOEJBQ1osbUJBQW1CLG9iQUNuQixZQUFZLDZLQUNaLG9CQUFvQiwrQkFDcEIsT0FBTyxzRUFDUCxTQUFTOzsyRkFHQSxvQkFBb0I7a0JBaEJoQyxTQUFTOytCQUVFLGNBQWMsaUJBRVQsaUJBQWlCLENBQUMsSUFBSSxjQUV6QixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixtQkFBbUI7d0JBQ25CLFlBQVk7d0JBQ1osb0JBQW9CO3dCQUNwQixPQUFPO3dCQUNQLFNBQVM7cUJBQ1Y7d0RBR1EsV0FBVztzQkFBbkIsS0FBSztnQkFNRyxTQUFTO3NCQUFqQixLQUFLO2dCQU9HLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBRUcsYUFBYTtzQkFBckIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQU9HLFdBQVc7c0JBQW5CLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMYXlvdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvbGF5b3V0JztcbmltcG9ydCB7IEFzeW5jUGlwZSwgTmdTdHlsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBGb3JtbHlGaWVsZENvbmZpZywgRm9ybWx5TW9kdWxlIH0gZnJvbSAnQG5neC1mb3JtbHkvY29yZSc7XG5pbXBvcnQgeyBGb3JtbHlNYXRlcmlhbE1vZHVsZSB9IGZyb20gJ0BuZ3gtZm9ybWx5L21hdGVyaWFsJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbnRlcmZhY2UgRm9ybUNvbmZpZ0VudHJ5IHtcbiAgZmllbGQ6IHN0cmluZztcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgdmFsdWU/OiBhbnk7XG4gIHJlcXVpcmVkPzogYm9vbGVhbjtcbiAgdHlwZT86IHN0cmluZztcbn1cblxuQENvbXBvbmVudCh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnY29udGFjdC1mb3JtJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NvbnRhY3QtZm9ybS5jb21wb25lbnQuaHRtbCcsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHN0eWxlVXJsczogWycuL2NvbnRhY3QtZm9ybS5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgTGF5b3V0TW9kdWxlLFxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgRm9ybWx5TW9kdWxlLFxuICAgIEZvcm1seU1hdGVyaWFsTW9kdWxlLFxuICAgIE5nU3R5bGUsXG4gICAgQXN5bmNQaXBlXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgQ29udGFjdEZvcm1Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGJ1dHRvblN0eWxlID0ge1xuICAgICdiYWNrZ3JvdW5kLWNvbG9yJzogJyMzMzMzMzMnLFxuICAgIGJvcmRlcjogJ25vbmUnLFxuICAgIGNvbG9yOiAnI2NjNzgzMidcbiAgfTtcblxuICBASW5wdXQoKSBmb3JtU3R5bGUgPSB7XG4gICAgY29sb3I6ICcjNDM3ZGE4JyxcbiAgICAnYmFja2dyb3VuZC1jb2xvcic6ICdyZ2JhKDM0LCAzNCwgMzQsIDAuNzUpJyxcbiAgICAnYmFja2Ryb3AtZmlsdGVyJzogJ2JsdXIoNTBweCknLFxuICAgICdib3gtc2hhZG93JzogJzAgMnB4IDEwcHggcmdiYSgwLCAwLCAwLCAwLjA3NSknXG4gIH07XG5cbiAgQElucHV0KCkgdGV4dFN0eWxlID0geyBjb2xvcjogJyNjYzc4MzInIH07XG5cbiAgQElucHV0KCkgc2VuZFRleHQgPSAnU2VuZCc7XG5cbiAgQElucHV0KCkgc2VuZFN1Y2Nlc3NmdWxUZXh0ID0gJ0UtTWFpbCBzdWNjZXNzZnVsbHkgc2VudCc7XG5cbiAgQElucHV0KCkgc2VuZEVycm9yVGV4dCA9ICdTZW5kIGVycm9yJztcblxuICBASW5wdXQoKSBmb3JtQ29uZmlnOiBGb3JtQ29uZmlnRW50cnlbXSA9IFtcbiAgICB7IGZpZWxkOiAnbmFtZScsIHJlcXVpcmVkOiB0cnVlIH0sXG4gICAgeyBmaWVsZDogJ2VtYWlsJywgcmVxdWlyZWQ6IHRydWUgfSxcbiAgICB7IGZpZWxkOiAnbWVzc2FnZScsIHJlcXVpcmVkOiB0cnVlLCB0eXBlOiAndGV4dGFyZWEnIH1cbiAgXTtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBASW5wdXQoKSBhcGlDYWxsYmFjayE6IChmb3JtVmFsdWU6IGFueSkgPT4gT2JzZXJ2YWJsZTxib29sZWFuPjtcblxuICBmb3JtID0gbmV3IEZvcm1Hcm91cCh7fSk7XG4gIGZpZWxkczogRm9ybWx5RmllbGRDb25maWdbXSA9IFtdO1xuICBtb2RlbDogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuXG4gIGVtYWlsU2VudDogU3ViamVjdDxib29sZWFuIHwgbnVsbD4gPSBuZXcgU3ViamVjdCgpO1xuICBlbWFpbFNlbnQkID0gdGhpcy5lbWFpbFNlbnQuYXNPYnNlcnZhYmxlKCk7XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZSQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdCgpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuZW1haWxTZW50Lm5leHQobnVsbCk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmJ1aWxkQ29uZmlnKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnVuc3Vic2NyaWJlJC5uZXh0KCk7XG4gICAgdGhpcy51bnN1YnNjcmliZSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHN1Ym1pdEZvcm1EYXRhKGZvcm1EYXRhOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KSB7XG4gICAgdGhpcy5hcGlDYWxsYmFjayhmb3JtRGF0YSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKHN1Y2Nlc3M6IGJvb2xlYW4pID0+IHRoaXMuZW1haWxTZW50Lm5leHQoc3VjY2VzcykpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy51bnN1YnNjcmliZSQpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkQ29uZmlnKCk6IHZvaWQge1xuICAgIHRoaXMuZm9ybUNvbmZpZy5mb3JFYWNoKChlbnRyeTogRm9ybUNvbmZpZ0VudHJ5KSA9PiB7XG4gICAgICBpZiAoZW50cnkudmFsdWUpIHtcbiAgICAgICAgdGhpcy5tb2RlbFtlbnRyeS5maWVsZF0gPSBlbnRyeS52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5maWVsZHMucHVzaCh7XG4gICAgICAgIGtleTogZW50cnkuZmllbGQsXG4gICAgICAgIHR5cGU6IGVudHJ5LnR5cGUgPyBlbnRyeS50eXBlIDogJ2lucHV0JyxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBsYWJlbDogZW50cnkuZmllbGQudG9Mb2NhbGVVcHBlckNhc2UoKSxcbiAgICAgICAgICBwbGFjZWhvbGRlcjogJ0VudGVyICcgKyBlbnRyeS5maWVsZCxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB7IHN0eWxlOiB0aGlzLmZsYXR0ZW5TdHlsZSh0aGlzLnRleHRTdHlsZSkgfVxuICAgICAgICB9LFxuICAgICAgICB0ZW1wbGF0ZU9wdGlvbnM6XG4gICAgICAgICAgZW50cnkudHlwZSA9PT0gJ3RleHRhcmVhJ1xuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgYXV0b3NpemU6IHRydWUsXG4gICAgICAgICAgICAgICAgbWluUm93czogNSxcbiAgICAgICAgICAgICAgICBtYXhSb3dzOiAxMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHt9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZmxhdHRlblN0eWxlKHN0eWxlT2JqZWN0OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogc3RyaW5nIHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoc3R5bGVPYmplY3QpXG4gICAgICAuZmxhdE1hcCgoZW50cnkpID0+IHtcbiAgICAgICAgcmV0dXJuIGAke2VudHJ5WzBdfTogJHtlbnRyeVsxXX07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG4gIH1cbn1cbiIsIjxmb3JtXG4gIFtuZ1N0eWxlXT1cImZvcm1TdHlsZVwiXG4gIGNsYXNzPVwiY29udGFjdC1mb3JtIGZsZXgtY29sdW1uIGZsZXgtZnhmbGV4XCJcbiAgW2Zvcm1Hcm91cF09XCJmb3JtXCJcbiAgKG5nU3VibWl0KT1cInN1Ym1pdEZvcm1EYXRhKG1vZGVsKVwiXG4+XG4gIDxmb3JtbHktZm9ybSBbZm9ybV09XCJmb3JtXCIgW2ZpZWxkc109XCJmaWVsZHNcIiBbbW9kZWxdPVwibW9kZWxcIj48L2Zvcm1seS1mb3JtPlxuICA8YnV0dG9uXG4gICAgW25nU3R5bGVdPVwiYnV0dG9uU3R5bGVcIlxuICAgIGNsYXNzPVwiZm9ybS1idXR0b25cIlxuICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgIFtkaXNhYmxlZF09XCIhZm9ybS52YWxpZFwiXG4gID5cbiAgICB7eyBzZW5kVGV4dCB9fVxuICA8L2J1dHRvbj5cbiAgPGRpdiBbbmdTdHlsZV09XCJ0ZXh0U3R5bGVcIiBjbGFzcz1cImZvcm0tc3RhdHVzXCI+XG4gICAgQGlmICgoZW1haWxTZW50JCB8IGFzeW5jKSA9PT0gdHJ1ZSkge1xuICAgICAge3sgc2VuZFN1Y2Nlc3NmdWxUZXh0IH19XG4gICAgfSBAZWxzZSBpZiAoKGVtYWlsU2VudCQgfCBhc3luYykgPT09IGZhbHNlKSB7XG4gICAgICB7eyBzZW5kRXJyb3JUZXh0IH19XG4gICAgfVxuICA8L2Rpdj5cbjwvZm9ybT5cbiJdfQ==
@@ -0,0 +1,122 @@
1
+ import { LayoutModule } from '@angular/cdk/layout';
2
+ import { NgStyle, AsyncPipe } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { Component, ViewEncapsulation, Input } from '@angular/core';
5
+ import * as i1 from '@angular/forms';
6
+ import { FormGroup, ReactiveFormsModule } from '@angular/forms';
7
+ import * as i2 from '@ngx-formly/core';
8
+ import { FormlyModule } from '@ngx-formly/core';
9
+ import { FormlyMaterialModule } from '@ngx-formly/material';
10
+ import { Subject } from 'rxjs';
11
+ import { tap, takeUntil } from 'rxjs/operators';
12
+
13
+ class ContactFormComponent {
14
+ constructor() {
15
+ this.buttonStyle = {
16
+ 'background-color': '#333333',
17
+ border: 'none',
18
+ color: '#cc7832'
19
+ };
20
+ this.formStyle = {
21
+ color: '#437da8',
22
+ 'background-color': 'rgba(34, 34, 34, 0.75)',
23
+ 'backdrop-filter': 'blur(50px)',
24
+ 'box-shadow': '0 2px 10px rgba(0, 0, 0, 0.075)'
25
+ };
26
+ this.textStyle = { color: '#cc7832' };
27
+ this.sendText = 'Send';
28
+ this.sendSuccessfulText = 'E-Mail successfully sent';
29
+ this.sendErrorText = 'Send error';
30
+ this.formConfig = [
31
+ { field: 'name', required: true },
32
+ { field: 'email', required: true },
33
+ { field: 'message', required: true, type: 'textarea' }
34
+ ];
35
+ this.form = new FormGroup({});
36
+ this.fields = [];
37
+ this.model = {};
38
+ this.emailSent = new Subject();
39
+ this.emailSent$ = this.emailSent.asObservable();
40
+ this.unsubscribe$ = new Subject();
41
+ this.emailSent.next(null);
42
+ }
43
+ ngOnInit() {
44
+ this.buildConfig();
45
+ }
46
+ ngOnDestroy() {
47
+ this.unsubscribe$.next();
48
+ this.unsubscribe$.complete();
49
+ }
50
+ submitFormData(formData) {
51
+ this.apiCallback(formData)
52
+ .pipe(tap((success) => this.emailSent.next(success)), takeUntil(this.unsubscribe$))
53
+ .subscribe();
54
+ }
55
+ buildConfig() {
56
+ this.formConfig.forEach((entry) => {
57
+ if (entry.value) {
58
+ this.model[entry.field] = entry.value;
59
+ }
60
+ this.fields.push({
61
+ key: entry.field,
62
+ type: entry.type ? entry.type : 'input',
63
+ props: {
64
+ label: entry.field.toLocaleUpperCase(),
65
+ placeholder: 'Enter ' + entry.field,
66
+ required: true,
67
+ attributes: { style: this.flattenStyle(this.textStyle) }
68
+ },
69
+ templateOptions: entry.type === 'textarea'
70
+ ? {
71
+ autosize: true,
72
+ minRows: 5,
73
+ maxRows: 10
74
+ }
75
+ : {}
76
+ });
77
+ });
78
+ }
79
+ flattenStyle(styleObject) {
80
+ return Object.entries(styleObject)
81
+ .flatMap((entry) => {
82
+ return `${entry[0]}: ${entry[1]};`;
83
+ })
84
+ .join('');
85
+ }
86
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: ContactFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
87
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.3", type: ContactFormComponent, isStandalone: true, selector: "contact-form", inputs: { buttonStyle: "buttonStyle", formStyle: "formStyle", textStyle: "textStyle", sendText: "sendText", sendSuccessfulText: "sendSuccessfulText", sendErrorText: "sendErrorText", formConfig: "formConfig", apiCallback: "apiCallback" }, ngImport: i0, template: "<form\n [ngStyle]=\"formStyle\"\n class=\"contact-form flex-column flex-fxflex\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submitFormData(model)\"\n>\n <formly-form [form]=\"form\" [fields]=\"fields\" [model]=\"model\"></formly-form>\n <button\n [ngStyle]=\"buttonStyle\"\n class=\"form-button\"\n type=\"submit\"\n [disabled]=\"!form.valid\"\n >\n {{ sendText }}\n </button>\n <div [ngStyle]=\"textStyle\" class=\"form-status\">\n @if ((emailSent$ | async) === true) {\n {{ sendSuccessfulText }}\n } @else if ((emailSent$ | async) === false) {\n {{ sendErrorText }}\n }\n </div>\n</form>\n", styles: [".contact-form{max-width:500px;margin:auto;padding:40px 40px 30px;box-sizing:border-box}.form-button{margin-top:.33rem;display:block;border-radius:.25rem;height:36px;width:100%;padding:.375rem .75rem}.form-status{height:19px;margin-top:1rem}.flex-align-start{justify-content:flex-start}.flex-align-stretch{align-content:stretch;align-items:stretch}.flex-column{display:flex;flex-direction:column;box-sizing:border-box}.flex-row{display:flex;flex-direction:row;box-sizing:border-box}.flex-row-wrap{display:flex;flex-direction:row;flex-wrap:wrap;box-sizing:border-box}.flex-fxflex{flex:1 1 0%}.flex-fxflex-responsive{flex:0 1 calc(33.3% - 32px)}.flex-fxflex-lt-md{flex:0 1 calc(50% - 32px)}.flex-fxflex-lt-sm{flex:100%}.flex-fxflex-fill{height:100%;min-height:100%;min-width:100%;width:100%}.flex-gap-5{margin-right:5px}.flex-gap-12{margin-right:12px}.flex-gap-20{margin-right:20px}\n"], dependencies: [{ kind: "ngmodule", type: LayoutModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i2.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: FormlyMaterialModule }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
88
+ }
89
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: ContactFormComponent, decorators: [{
90
+ type: Component,
91
+ args: [{ selector: 'contact-form', encapsulation: ViewEncapsulation.None, standalone: true, imports: [
92
+ LayoutModule,
93
+ ReactiveFormsModule,
94
+ FormlyModule,
95
+ FormlyMaterialModule,
96
+ NgStyle,
97
+ AsyncPipe
98
+ ], template: "<form\n [ngStyle]=\"formStyle\"\n class=\"contact-form flex-column flex-fxflex\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submitFormData(model)\"\n>\n <formly-form [form]=\"form\" [fields]=\"fields\" [model]=\"model\"></formly-form>\n <button\n [ngStyle]=\"buttonStyle\"\n class=\"form-button\"\n type=\"submit\"\n [disabled]=\"!form.valid\"\n >\n {{ sendText }}\n </button>\n <div [ngStyle]=\"textStyle\" class=\"form-status\">\n @if ((emailSent$ | async) === true) {\n {{ sendSuccessfulText }}\n } @else if ((emailSent$ | async) === false) {\n {{ sendErrorText }}\n }\n </div>\n</form>\n", styles: [".contact-form{max-width:500px;margin:auto;padding:40px 40px 30px;box-sizing:border-box}.form-button{margin-top:.33rem;display:block;border-radius:.25rem;height:36px;width:100%;padding:.375rem .75rem}.form-status{height:19px;margin-top:1rem}.flex-align-start{justify-content:flex-start}.flex-align-stretch{align-content:stretch;align-items:stretch}.flex-column{display:flex;flex-direction:column;box-sizing:border-box}.flex-row{display:flex;flex-direction:row;box-sizing:border-box}.flex-row-wrap{display:flex;flex-direction:row;flex-wrap:wrap;box-sizing:border-box}.flex-fxflex{flex:1 1 0%}.flex-fxflex-responsive{flex:0 1 calc(33.3% - 32px)}.flex-fxflex-lt-md{flex:0 1 calc(50% - 32px)}.flex-fxflex-lt-sm{flex:100%}.flex-fxflex-fill{height:100%;min-height:100%;min-width:100%;width:100%}.flex-gap-5{margin-right:5px}.flex-gap-12{margin-right:12px}.flex-gap-20{margin-right:20px}\n"] }]
99
+ }], ctorParameters: () => [], propDecorators: { buttonStyle: [{
100
+ type: Input
101
+ }], formStyle: [{
102
+ type: Input
103
+ }], textStyle: [{
104
+ type: Input
105
+ }], sendText: [{
106
+ type: Input
107
+ }], sendSuccessfulText: [{
108
+ type: Input
109
+ }], sendErrorText: [{
110
+ type: Input
111
+ }], formConfig: [{
112
+ type: Input
113
+ }], apiCallback: [{
114
+ type: Input
115
+ }] } });
116
+
117
+ /**
118
+ * Generated bundle index. Do not edit.
119
+ */
120
+
121
+ export { ContactFormComponent };
122
+ //# sourceMappingURL=tehw0lf-contact-form.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tehw0lf-contact-form.mjs","sources":["../../../../libs/contact-form/src/lib/contact-form/contact-form.component.ts","../../../../libs/contact-form/src/lib/contact-form/contact-form.component.html","../../../../libs/contact-form/src/tehw0lf-contact-form.ts"],"sourcesContent":["import { LayoutModule } from '@angular/cdk/layout';\nimport { AsyncPipe, NgStyle } from '@angular/common';\nimport {\n Component,\n Input,\n OnDestroy,\n OnInit,\n ViewEncapsulation\n} from '@angular/core';\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { FormlyFieldConfig, FormlyModule } from '@ngx-formly/core';\nimport { FormlyMaterialModule } from '@ngx-formly/material';\nimport { Observable, Subject } from 'rxjs';\nimport { takeUntil, tap } from 'rxjs/operators';\n\ninterface FormConfigEntry {\n field: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value?: any;\n required?: boolean;\n type?: string;\n}\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'contact-form',\n templateUrl: './contact-form.component.html',\n encapsulation: ViewEncapsulation.None,\n styleUrls: ['./contact-form.component.scss'],\n standalone: true,\n imports: [\n LayoutModule,\n ReactiveFormsModule,\n FormlyModule,\n FormlyMaterialModule,\n NgStyle,\n AsyncPipe\n ]\n})\nexport class ContactFormComponent implements OnInit, OnDestroy {\n @Input() buttonStyle = {\n 'background-color': '#333333',\n border: 'none',\n color: '#cc7832'\n };\n\n @Input() formStyle = {\n color: '#437da8',\n 'background-color': 'rgba(34, 34, 34, 0.75)',\n 'backdrop-filter': 'blur(50px)',\n 'box-shadow': '0 2px 10px rgba(0, 0, 0, 0.075)'\n };\n\n @Input() textStyle = { color: '#cc7832' };\n\n @Input() sendText = 'Send';\n\n @Input() sendSuccessfulText = 'E-Mail successfully sent';\n\n @Input() sendErrorText = 'Send error';\n\n @Input() formConfig: FormConfigEntry[] = [\n { field: 'name', required: true },\n { field: 'email', required: true },\n { field: 'message', required: true, type: 'textarea' }\n ];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n @Input() apiCallback!: (formValue: any) => Observable<boolean>;\n\n form = new FormGroup({});\n fields: FormlyFieldConfig[] = [];\n model: { [key: string]: string } = {};\n\n emailSent: Subject<boolean | null> = new Subject();\n emailSent$ = this.emailSent.asObservable();\n\n private unsubscribe$: Subject<void> = new Subject();\n\n constructor() {\n this.emailSent.next(null);\n }\n\n ngOnInit(): void {\n this.buildConfig();\n }\n\n ngOnDestroy(): void {\n this.unsubscribe$.next();\n this.unsubscribe$.complete();\n }\n\n submitFormData(formData: { [key: string]: string }) {\n this.apiCallback(formData)\n .pipe(\n tap((success: boolean) => this.emailSent.next(success)),\n takeUntil(this.unsubscribe$)\n )\n .subscribe();\n }\n\n private buildConfig(): void {\n this.formConfig.forEach((entry: FormConfigEntry) => {\n if (entry.value) {\n this.model[entry.field] = entry.value;\n }\n\n this.fields.push({\n key: entry.field,\n type: entry.type ? entry.type : 'input',\n props: {\n label: entry.field.toLocaleUpperCase(),\n placeholder: 'Enter ' + entry.field,\n required: true,\n attributes: { style: this.flattenStyle(this.textStyle) }\n },\n templateOptions:\n entry.type === 'textarea'\n ? {\n autosize: true,\n minRows: 5,\n maxRows: 10\n }\n : {}\n });\n });\n }\n\n private flattenStyle(styleObject: { [key: string]: string }): string {\n return Object.entries(styleObject)\n .flatMap((entry) => {\n return `${entry[0]}: ${entry[1]};`;\n })\n .join('');\n }\n}\n","<form\n [ngStyle]=\"formStyle\"\n class=\"contact-form flex-column flex-fxflex\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submitFormData(model)\"\n>\n <formly-form [form]=\"form\" [fields]=\"fields\" [model]=\"model\"></formly-form>\n <button\n [ngStyle]=\"buttonStyle\"\n class=\"form-button\"\n type=\"submit\"\n [disabled]=\"!form.valid\"\n >\n {{ sendText }}\n </button>\n <div [ngStyle]=\"textStyle\" class=\"form-status\">\n @if ((emailSent$ | async) === true) {\n {{ sendSuccessfulText }}\n } @else if ((emailSent$ | async) === false) {\n {{ sendErrorText }}\n }\n </div>\n</form>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,2 +1 @@
1
- export * from './lib/contact-form.module';
2
1
  export * from './lib/contact-form/contact-form.component';
@@ -1,11 +1,15 @@
1
- import { OnDestroy } from '@angular/core';
2
- import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
3
- import { Subject } from 'rxjs';
4
- import { EmailApiService } from '../email-api.service';
1
+ import { OnDestroy, OnInit } from '@angular/core';
2
+ import { FormGroup } from '@angular/forms';
3
+ import { FormlyFieldConfig } from '@ngx-formly/core';
4
+ import { Observable, Subject } from 'rxjs';
5
5
  import * as i0 from "@angular/core";
6
- export declare class ContactFormComponent implements OnDestroy {
7
- private builder;
8
- private emailService;
6
+ interface FormConfigEntry {
7
+ field: string;
8
+ value?: any;
9
+ required?: boolean;
10
+ type?: string;
11
+ }
12
+ export declare class ContactFormComponent implements OnInit, OnDestroy {
9
13
  buttonStyle: {
10
14
  'background-color': string;
11
15
  border: string;
@@ -17,27 +21,31 @@ export declare class ContactFormComponent implements OnDestroy {
17
21
  'backdrop-filter': string;
18
22
  'box-shadow': string;
19
23
  };
20
- inputStyle: {
21
- color: string;
22
- };
23
24
  textStyle: {
24
25
  color: string;
25
26
  };
26
- nameLabel: string;
27
- emailAddressLabel: string;
28
- messageLabel: string;
29
27
  sendText: string;
30
28
  sendSuccessfulText: string;
31
29
  sendErrorText: string;
32
- apiURL: string;
33
- email: string;
34
- formGroup: UntypedFormGroup;
30
+ formConfig: FormConfigEntry[];
31
+ apiCallback: (formValue: any) => Observable<boolean>;
32
+ form: FormGroup<{}>;
33
+ fields: FormlyFieldConfig[];
34
+ model: {
35
+ [key: string]: string;
36
+ };
35
37
  emailSent: Subject<boolean | null>;
36
- emailSent$: import("rxjs").Observable<boolean | null>;
38
+ emailSent$: Observable<boolean | null>;
37
39
  private unsubscribe$;
38
- constructor(builder: UntypedFormBuilder, emailService: EmailApiService);
40
+ constructor();
41
+ ngOnInit(): void;
39
42
  ngOnDestroy(): void;
40
- submitFormData(formData: UntypedFormGroup): void;
43
+ submitFormData(formData: {
44
+ [key: string]: string;
45
+ }): void;
46
+ private buildConfig;
47
+ private flattenStyle;
41
48
  static ɵfac: i0.ɵɵFactoryDeclaration<ContactFormComponent, never>;
42
- static ɵcmp: i0.ɵɵComponentDeclaration<ContactFormComponent, "contact-form", never, { "buttonStyle": "buttonStyle"; "formStyle": "formStyle"; "inputStyle": "inputStyle"; "textStyle": "textStyle"; "nameLabel": "nameLabel"; "emailAddressLabel": "emailAddressLabel"; "messageLabel": "messageLabel"; "sendText": "sendText"; "sendSuccessfulText": "sendSuccessfulText"; "sendErrorText": "sendErrorText"; "apiURL": "apiURL"; "email": "email"; }, {}, never, never, false>;
49
+ static ɵcmp: i0.ɵɵComponentDeclaration<ContactFormComponent, "contact-form", never, { "buttonStyle": { "alias": "buttonStyle"; "required": false; }; "formStyle": { "alias": "formStyle"; "required": false; }; "textStyle": { "alias": "textStyle"; "required": false; }; "sendText": { "alias": "sendText"; "required": false; }; "sendSuccessfulText": { "alias": "sendSuccessfulText"; "required": false; }; "sendErrorText": { "alias": "sendErrorText"; "required": false; }; "formConfig": { "alias": "formConfig"; "required": false; }; "apiCallback": { "alias": "apiCallback"; "required": false; }; }, {}, never, never, true, never>;
43
50
  }
51
+ export {};
package/package.json CHANGED
@@ -1,33 +1,25 @@
1
1
  {
2
2
  "name": "@tehw0lf/contact-form",
3
- "version": "0.14.4",
3
+ "version": "0.17.5",
4
4
  "license": "MIT",
5
- "homepage": "https://github.com/tehw0lf/tehwol.fi.git",
5
+ "homepage": "https://github.com/tehw0lf/tehwolf.de.git",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/tehw0lf/tehwol.fi.git"
8
+ "url": "https://github.com/tehw0lf/tehwolf.de.git"
9
9
  },
10
10
  "peerDependencies": {
11
- "@angular/animations": "^14.1.3",
12
- "@angular/cdk": "^14.1.3",
13
- "@angular/common": "^14.1.3",
14
- "@angular/core": "^14.1.3",
15
- "@angular/flex-layout": "^14.0.0-beta.40",
16
- "@angular/forms": "^14.1.3",
17
- "@angular/material": "^14.1.3",
18
- "@angular/platform-browser": "14.1.3",
19
- "rxjs": "7.5.6",
20
- "@angular/platform-browser-dynamic": "14.1.3"
11
+ "@angular/animations": "17.3.3",
12
+ "@angular/common": "17.3.3",
13
+ "@angular/core": "17.3.3",
14
+ "@angular/forms": "17.3.3",
15
+ "@ngx-formly/core": "^6.3.0",
16
+ "@ngx-formly/material": "^6.3.0",
17
+ "@tehw0lf/mvc": "^0.0.2"
21
18
  },
22
19
  "dependencies": {
23
20
  "tslib": "^2.2.0"
24
21
  },
25
- "schematics": "./schematics/collection.json",
26
- "module": "fesm2015/tehw0lf-contact-form.mjs",
27
- "es2020": "fesm2020/tehw0lf-contact-form.mjs",
28
- "esm2020": "esm2020/tehw0lf-contact-form.mjs",
29
- "fesm2020": "fesm2020/tehw0lf-contact-form.mjs",
30
- "fesm2015": "fesm2015/tehw0lf-contact-form.mjs",
22
+ "module": "fesm2022/tehw0lf-contact-form.mjs",
31
23
  "typings": "index.d.ts",
32
24
  "exports": {
33
25
  "./package.json": {
@@ -35,12 +27,10 @@
35
27
  },
36
28
  ".": {
37
29
  "types": "./index.d.ts",
38
- "esm2020": "./esm2020/tehw0lf-contact-form.mjs",
39
- "es2020": "./fesm2020/tehw0lf-contact-form.mjs",
40
- "es2015": "./fesm2015/tehw0lf-contact-form.mjs",
41
- "node": "./fesm2015/tehw0lf-contact-form.mjs",
42
- "default": "./fesm2020/tehw0lf-contact-form.mjs"
30
+ "esm2022": "./esm2022/tehw0lf-contact-form.mjs",
31
+ "esm": "./esm2022/tehw0lf-contact-form.mjs",
32
+ "default": "./fesm2022/tehw0lf-contact-form.mjs"
43
33
  }
44
34
  },
45
35
  "sideEffects": false
46
- }
36
+ }
package/esm2020/index.mjs DELETED
@@ -1,3 +0,0 @@
1
- export * from './lib/contact-form.module';
2
- export * from './lib/contact-form/contact-form.component';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzL2NvbnRhY3QtZm9ybS9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywyQkFBMkIsQ0FBQztBQUMxQyxjQUFjLDJDQUEyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9saWIvY29udGFjdC1mb3JtLm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250YWN0LWZvcm0vY29udGFjdC1mb3JtLmNvbXBvbmVudCc7XG4iXX0=