@klippa/ngx-enhancy-forms 1.2.0 → 2.2.0

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 (44) hide show
  1. package/README.md +179 -23
  2. package/bundles/klippa-ngx-enhancy-forms.umd.js +288 -97
  3. package/bundles/klippa-ngx-enhancy-forms.umd.js.map +1 -1
  4. package/bundles/klippa-ngx-enhancy-forms.umd.min.js +2 -2
  5. package/bundles/klippa-ngx-enhancy-forms.umd.min.js.map +1 -1
  6. package/esm2015/klippa-ngx-enhancy-forms.js +2 -17
  7. package/esm2015/lib/elements/button/button.component.js +3 -3
  8. package/esm2015/lib/elements/checkbox/checkbox.component.js +1 -1
  9. package/esm2015/lib/elements/datepicker/datepicker.component.js +111 -0
  10. package/esm2015/lib/elements/email/email-input.component.js +6 -2
  11. package/esm2015/lib/elements/loading-indicator/loading-indicator.component.js +2 -2
  12. package/esm2015/lib/elements/number-input/number-input.component.js +1 -1
  13. package/esm2015/lib/elements/password-field/password-field.component.js +11 -4
  14. package/esm2015/lib/elements/select/select.component.js +8 -12
  15. package/esm2015/lib/elements/sortable-items/sortable-items.component.js +1 -1
  16. package/esm2015/lib/elements/text-input/text-input.component.js +1 -1
  17. package/esm2015/lib/elements/toggle/toggle.component.js +1 -1
  18. package/esm2015/lib/elements/value-accessor-base/value-accessor-base.component.js +1 -1
  19. package/esm2015/lib/form/form-caption/form-caption.component.js +1 -1
  20. package/esm2015/lib/form/form-element/form-element.component.js +29 -5
  21. package/esm2015/lib/form/form-error/form-error.component.js +1 -1
  22. package/esm2015/lib/form/form-submit-button/form-submit-button.component.js +18 -7
  23. package/esm2015/lib/form/form.component.js +21 -7
  24. package/esm2015/lib/material.module.js +17 -0
  25. package/esm2015/lib/ngx-enhancy-forms.module.js +11 -6
  26. package/esm2015/lib/types.js +2 -0
  27. package/esm2015/lib/util/values.js +1 -1
  28. package/esm2015/lib/validators/dateValidator.js +6 -0
  29. package/esm2015/public-api.js +20 -1
  30. package/fesm2015/klippa-ngx-enhancy-forms.js +255 -70
  31. package/fesm2015/klippa-ngx-enhancy-forms.js.map +1 -1
  32. package/klippa-ngx-enhancy-forms.d.ts +1 -16
  33. package/klippa-ngx-enhancy-forms.metadata.json +1 -1
  34. package/lib/elements/datepicker/datepicker.component.d.ts +26 -0
  35. package/lib/elements/password-field/password-field.component.d.ts +1 -0
  36. package/lib/elements/select/select.component.d.ts +3 -3
  37. package/lib/form/form-element/form-element.component.d.ts +9 -2
  38. package/lib/form/form-error/form-error.component.d.ts +2 -1
  39. package/lib/form/form.component.d.ts +2 -0
  40. package/lib/material.module.d.ts +2 -0
  41. package/lib/types.d.ts +15 -0
  42. package/lib/validators/dateValidator.d.ts +3 -0
  43. package/package.json +8 -9
  44. package/public-api.d.ts +19 -0
@@ -1,10 +1,16 @@
1
- import { Component, Input, Host, Optional, ViewChild, ContentChild, TemplateRef, HostBinding, NgModule } from '@angular/core';
1
+ import { Component, Input, InjectionToken, Host, Optional, Inject, ViewChild, HostBinding, EventEmitter, Output, ContentChild, TemplateRef, NgModule } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormGroup, FormArray, FormControl, ControlContainer, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
4
4
  import { isString } from 'lodash';
5
- import { NgSelectModule } from '@ng-select/ng-select';
6
5
  import { SortablejsModule } from 'ngx-sortablejs';
6
+ import { NgSelectModule } from '@ng-select/ng-select';
7
+ import { MAT_NATIVE_DATE_FORMATS, MAT_DATE_FORMATS, MatNativeDateModule } from '@angular/material/core';
8
+ import { MatDatepickerModule } from '@angular/material/datepicker';
9
+ import { MatFormFieldModule } from '@angular/material/form-field';
10
+ import { MatInputModule } from '@angular/material/input';
11
+ import { MatButtonModule } from '@angular/material/button';
7
12
 
13
+ const invalidFieldsSymbol = Symbol('Not all fields are valid');
8
14
  class FormComponent {
9
15
  constructor() {
10
16
  // we keep track of what form controls are actually rendered. Only those count when looking at form validation
@@ -43,25 +49,38 @@ class FormComponent {
43
49
  });
44
50
  }
45
51
  disableInactiveFormControl(control) {
46
- if (this.activeControls.some((e) => e.formControl === control)) {
47
- control.enable();
48
- }
49
- else {
52
+ if (!this.activeControls.some((e) => e.formControl === control)) {
50
53
  control.disable();
51
54
  }
52
55
  }
53
56
  trySubmit() {
54
57
  var _a, _b;
55
58
  this.formGroup.markAllAsTouched();
59
+ const originalDisabledStates = Object.values(this.formGroup.controls).map(e => {
60
+ return { control: e, disabled: e.disabled };
61
+ });
56
62
  this.disableInactiveFormGroupControls(this.formGroup);
63
+ const values = this.formGroup.value;
57
64
  if (this.formGroup.valid) {
58
- return Promise.resolve(this.formGroup.value);
65
+ this.setDisabledStatesForAllControls(originalDisabledStates);
66
+ return Promise.resolve(values);
59
67
  }
60
68
  else {
61
69
  (_b = (_a = this.activeControls.find((e) => !e.formControl.valid)) === null || _a === void 0 ? void 0 : _a.formElement) === null || _b === void 0 ? void 0 : _b.scrollTo();
62
- return Promise.reject('Not all fields are valid');
70
+ this.setDisabledStatesForAllControls(originalDisabledStates);
71
+ return Promise.reject(invalidFieldsSymbol);
63
72
  }
64
73
  }
74
+ setDisabledStatesForAllControls(originalDisabledStates) {
75
+ originalDisabledStates.forEach((e) => {
76
+ if (e.disabled) {
77
+ e.control.disable();
78
+ }
79
+ else {
80
+ e.control.enable();
81
+ }
82
+ });
83
+ }
65
84
  }
66
85
  FormComponent.decorators = [
67
86
  { type: Component, args: [{
@@ -74,14 +93,33 @@ FormComponent.propDecorators = {
74
93
  formGroup: [{ type: Input }]
75
94
  };
76
95
 
96
+ const FORM_ERROR_MESSAGES = new InjectionToken('form.error.messages');
97
+ const DEFAULT_ERROR_MESSAGES = {
98
+ min: "Use a number larger than %min%",
99
+ max: "Use a number smaller than %max%",
100
+ required: "This field is required",
101
+ email: "Use a valid email address",
102
+ minLength: "Has to be longer than %minLength% character(s)",
103
+ maxLength: "Has to be shorter than %maxLength% character(s)",
104
+ pattern: "This input is not valid",
105
+ matchPassword: "Passwords must match",
106
+ date: "Enter a valid date",
107
+ };
77
108
  class FormElementComponent {
78
- constructor(parent) {
109
+ constructor(parent, customMessages) {
79
110
  this.parent = parent;
111
+ this.customMessages = customMessages;
80
112
  this.direction = 'horizontal';
81
113
  this.captionSpacing = 'percentages';
82
114
  this.swapInputAndCaption = false;
115
+ this.errorMessages = DEFAULT_ERROR_MESSAGES;
83
116
  this.customErrorHandlers = [];
84
117
  }
118
+ substituteParameters(message, parameters) {
119
+ return Object.keys(parameters).reduce((msg, key) => {
120
+ return msg.replace(`%${key}%`, parameters[key]);
121
+ }, message);
122
+ }
85
123
  registerControl(formControl) {
86
124
  this.attachedControl = formControl;
87
125
  this.parent.registerControl(formControl, this);
@@ -129,16 +167,21 @@ class FormElementComponent {
129
167
  // to give some breathing room, we scroll 100px more to the top
130
168
  (_a = this.getScrollableParent(this.internalComponentRef.nativeElement)) === null || _a === void 0 ? void 0 : _a.scrollBy(0, -100);
131
169
  }
170
+ getErrorMessages(key) {
171
+ var _a, _b, _c;
172
+ return (_c = (_b = (_a = this.customMessages) === null || _a === void 0 ? void 0 : _a[key]) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : this.errorMessages[key];
173
+ }
132
174
  }
133
175
  FormElementComponent.decorators = [
134
176
  { type: Component, args: [{
135
177
  selector: 'klp-form-element',
136
- template: "<ng-template #errorRef>\n\t<div *ngIf=\"getErrorToShow()\" class=\"errorContainer\">\n\t\t<div *ngIf=\"showDefaultError('min')\" translate [translateParams]=\"{min: attachedControl.errors.min.min}\">Use a number larger than %min%</div>\n\t\t<div *ngIf=\"showDefaultError('max')\" translate [translateParams]=\"{max: attachedControl.errors.max.max}\">Use a number smaller than %max%</div>\n\t\t<div *ngIf=\"showDefaultError('required')\" translate>This field is required</div>\n\t\t<div *ngIf=\"showDefaultError('email')\" translate>Use a valid email address</div>\n\t\t<div *ngIf=\"showDefaultError('minlength')\" translate [translateParams]=\"{minLength: attachedControl.errors.minlength.requiredLength}\">Has to be longer than %minLength% character(s)</div>\n\t\t<div *ngIf=\"showDefaultError('maxlength')\" translate [translateParams]=\"{maxlength: attachedControl.errors.maxlength.requiredLength}\">Has to be shorter than %maxlength% character(s)</div>\n\t\t<div *ngIf=\"showDefaultError('pattern')\" translate>This input is not valid</div>\n\t\t<div *ngIf=\"showDefaultError('MatchPassword')\" translate>Passwords must match</div>\n\t\t<div *ngIf=\"showDefaultError('date')\" translate>Enter a valid date</div>\n\t\t<div *ngIf=\"showDefaultError('message')\" translate>{{attachedControl.errors.message.value}}</div>\n\t\t<div [ngTemplateOutlet]=\"getCustomErrorHandler(getErrorToShow())?.templateRef\"></div>\n\t</div>\n</ng-template>\n<ng-container *ngIf=\"direction === 'horizontal'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n<div *ngIf=\"attachedControl\" class=\"componentContainer\" [ngClass]=\"{vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" [ngClass]=\"{ hasErrors: getErrorToShow() && attachedControl.touched, percentageSpacing: captionSpacing === 'percentages' }\">\n\t\t<div *ngIf=\"captionRef\" [ngTemplateOutlet]=\"captionRef\"></div>\n\t\t<div *ngIf=\"!captionRef\">{{caption}}</div>\n\t</div>\n\t<ng-container *ngIf=\"direction === 'vertical'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{ percentageSpacing: captionSpacing === 'percentages' }\">\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n",
178
+ template: "<ng-template #errorRef>\n\t<div *ngIf=\"getErrorToShow()\" class=\"errorContainer\">\n\t\t<div *ngIf=\"showDefaultError('min')\">{{substituteParameters(getErrorMessages(\"min\"), {min: attachedControl.errors.min.min})}}</div>\n\t\t<div *ngIf=\"showDefaultError('max')\">{{substituteParameters(getErrorMessages(\"max\"), {max: attachedControl.errors.max.max})}}</div>\n\t\t<div *ngIf=\"showDefaultError('required')\">{{getErrorMessages(\"required\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('email')\">{{getErrorMessages(\"email\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('minlength')\">{{substituteParameters(getErrorMessages(\"minLength\"), {minLength: attachedControl.errors.minlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('maxlength')\">{{substituteParameters(getErrorMessages(\"maxLength\"), {maxLength: attachedControl.errors.maxlength.requiredLength})}}</div>\n\t\t<div *ngIf=\"showDefaultError('pattern')\">{{getErrorMessages(\"pattern\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('MatchPassword')\">{{getErrorMessages(\"matchPassword\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('date')\">{{getErrorMessages(\"date\")}}</div>\n\t\t<div *ngIf=\"showDefaultError('message')\">{{attachedControl.errors.message.value}}</div>\n\t\t<div [ngTemplateOutlet]=\"getCustomErrorHandler(getErrorToShow())?.templateRef\"></div>\n\t</div>\n</ng-template>\n<ng-container *ngIf=\"direction === 'horizontal'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n<div *ngIf=\"attachedControl\" class=\"componentContainer\" [ngClass]=\"{vertical: direction === 'vertical', reverseOrder: swapInputAndCaption}\" #internalComponentRef>\n\t<div class=\"caption\" [ngClass]=\"{ hasErrors: getErrorToShow() && attachedControl.touched, percentageSpacing: captionSpacing === 'percentages' }\">\n\t\t<div *ngIf=\"captionRef\" [ngTemplateOutlet]=\"captionRef\"></div>\n\t\t<div *ngIf=\"!captionRef\">{{caption}}</div>\n\t</div>\n\t<ng-container *ngIf=\"direction === 'vertical'\" [ngTemplateOutlet]=\"errorRef\"></ng-container>\n\t<div class=\"inputContainer\" [ngClass]=\"{ percentageSpacing: captionSpacing === 'percentages' }\">\n\t\t<ng-content></ng-content>\n\t</div>\n</div>\n",
137
179
  styles: [":host{display:block;margin-top:1.25rem}.componentContainer{align-items:center;display:flex}.componentContainer.reverseOrder{flex-direction:row-reverse;justify-content:flex-end}.componentContainer.vertical{display:block;margin-bottom:1rem}.componentContainer.vertical .inputContainer{margin-top:.3125rem}.componentContainer.vertical .errorContainer{margin-left:0}.caption{color:#515365;flex:0 0 auto;font-weight:700}.caption.percentageSpacing{flex:0 0 40%}.caption.hasErrors{color:#ff8000}.inputContainer{flex:0 0 auto}.inputContainer.percentageSpacing{flex:0 0 60%}.errorContainer{color:#ff8000;margin-left:40%}"]
138
180
  },] }
139
181
  ];
140
182
  FormElementComponent.ctorParameters = () => [
141
- { type: FormComponent, decorators: [{ type: Host }, { type: Optional }] }
183
+ { type: FormComponent, decorators: [{ type: Host }, { type: Optional }] },
184
+ { type: undefined, decorators: [{ type: Inject, args: [FORM_ERROR_MESSAGES,] }, { type: Optional }] }
142
185
  ];
143
186
  FormElementComponent.propDecorators = {
144
187
  caption: [{ type: Input }],
@@ -269,6 +312,43 @@ ValueAccessorBase.propDecorators = {
269
312
  formControl: [{ type: Input }]
270
313
  };
271
314
 
315
+ class ButtonComponent {
316
+ constructor() {
317
+ this.variant = 'white';
318
+ this.size = 'medium';
319
+ this.fullWidth = false;
320
+ this.hasBorder = true;
321
+ this.disabled = false;
322
+ this.isLoading = false;
323
+ this.type = 'button';
324
+ }
325
+ get _() {
326
+ return this.fullWidth;
327
+ }
328
+ onClick(event) {
329
+ if (this.disabled) {
330
+ event.stopPropagation();
331
+ }
332
+ }
333
+ }
334
+ ButtonComponent.decorators = [
335
+ { type: Component, args: [{
336
+ selector: 'klp-form-button',
337
+ template: "<button class=\"buttonFundamentals\"\n\t[ngClass]=\"[\n\t\tvariant,\n\t\tsize,\n\t\tfullWidth ? 'fullWidth' : '',\n\t\thasBorder ? '' : 'no-border',\n\t\tdisabled ? 'disabled' : ''\n\t]\"\n\t[type]=\"type\"\n\t(click)=\"onClick($event)\"\n>\n\t<div class=\"caption\" [ngClass]=\"{invisible: isLoading}\">\n\t\t<ng-content></ng-content>\n\t</div>\n\t<div class=\"loadingSpinnerContainer\" *ngIf=\"isLoading\">\n\t\t<klp-form-loading-indicator variant=\"spinner\" size=\"small\"></klp-form-loading-indicator>\n\t</div>\n</button>\n",
338
+ styles: [":host{display:inline-block}:host._fullWidth{display:block}.buttonFundamentals{border:1px solid #e6ecf5;border-radius:5px;color:#888da8;cursor:pointer;font-size:13px;font-weight:700;letter-spacing:1px;padding:10px 20px}.fullWidth{width:100%}.no-border{border:none}.caption.invisible{visibility:hidden}button{position:relative}.loadingSpinnerContainer{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0}.small{padding-bottom:.375rem;padding-top:.375rem}.large{line-height:2}.white{background-color:#fff;border-color:#d4deee;color:#515365;font-weight:500}.white:active,.white:hover{background-color:#edf2f8;border-color:#edf2f8;color:#515365}.white:focus{text-decoration:underline}.greenFilled{background-color:#27bb5f;border-color:#27bb5f;color:#fff}.greenFilled:hover{background-color:#2bd06a;border-color:#2bd06a;color:#fff}.greenFilled:focus{text-decoration:underline}.greenFilled:active{background-color:#23a654;border-color:#23a654}.greenOutlined{background-color:#fff;border-color:#27bb5f;color:#27bb5f}.greenOutlined:hover{background-color:#2bd06a;border-color:#2bd06a;color:#fff}.greenOutlined:focus{text-decoration:underline}.greenOutlined:active{background-color:#23a654;border-color:#23a654}.greenLink{background:none;border:none;color:#27bb5f;padding:0}.greenLink:focus,.greenLink:hover{text-decoration:underline}.contextMenuItem{background-color:#fff;border-color:#fff;color:#888da8}.contextMenuItem:hover{background-color:#f6f7fb;border-color:#f6f7fb}.contextMenuItem:active,.contextMenuItem:focus{text-decoration:underline}.redFilled{background-color:#ff3c7e;border-color:#ff3c7e;color:#fff}.redFilled:hover{background-color:#ff568f;border-color:#ff568f;color:#fff}.redFilled:focus{text-decoration:underline}.redFilled:active{background-color:#ff236d;border-color:#ff236d}.redOutlined{background-color:#fff;border-color:#ff3c7e;color:#ff3c7e}.redOutlined:hover{background-color:#ff568f;border-color:#ff568f;color:#fff}.redOutlined:focus{text-decoration:underline}.redOutlined:active{background-color:#ff236d;border-color:#ff236d}.orangeFilled{background-color:#ff8000;border-color:#ff8000;color:#fff}.orangeFilled:hover{background-color:#ff8d1a;border-color:#ff8d1a;color:#fff}.orangeFilled:focus{text-decoration:underline}.orangeFilled:active{background-color:#e67300;border-color:#e67300}"]
339
+ },] }
340
+ ];
341
+ ButtonComponent.propDecorators = {
342
+ variant: [{ type: Input }],
343
+ size: [{ type: Input }],
344
+ fullWidth: [{ type: Input }],
345
+ hasBorder: [{ type: Input }],
346
+ disabled: [{ type: Input }],
347
+ isLoading: [{ type: Input }],
348
+ type: [{ type: Input }],
349
+ _: [{ type: HostBinding, args: ['class._fullWidth',] }]
350
+ };
351
+
272
352
  class CheckboxComponent extends ValueAccessorBase {
273
353
  }
274
354
  CheckboxComponent.decorators = [
@@ -285,11 +365,15 @@ CheckboxComponent.propDecorators = {
285
365
  };
286
366
 
287
367
  class EmailInputComponent extends ValueAccessorBase {
368
+ constructor() {
369
+ super(...arguments);
370
+ this.placeholder = '';
371
+ }
288
372
  }
289
373
  EmailInputComponent.decorators = [
290
374
  { type: Component, args: [{
291
375
  selector: 'klp-form-email-input',
292
- template: "<input\n\ttype=\"email\"\n\tclass=\"form-control\"\n\t[(ngModel)]=\"innerValue\"\n\t(input)=\"setInnerValueAndNotify($event.target.value)\"\n\t[placeholder]=\"placeholder ? placeholder : ''\"\n\t(blur)=\"touch()\"\n/>\n",
376
+ template: "<input\n\ttype=\"email\"\n\tclass=\"form-control\"\n\t[(ngModel)]=\"innerValue\"\n\t(input)=\"setInnerValueAndNotify($event.target.value)\"\n\t[placeholder]=\"placeholder\"\n\t(blur)=\"touch()\"\n/>\n",
293
377
  providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: EmailInputComponent, multi: true }],
294
378
  styles: [":host,input{display:block}input{-moz-transition:all .2s ease-in;-ms-transition:all .2s ease-in;-o-transition:all .2s ease-in;-webkit-transition:all .2s ease-in;border:1px solid #e6ecf5;border-radius:2px;box-shadow:none;color:#888da8;font-size:14px;height:42px;outline:none;padding:.375rem .625rem;transition:all .2s ease-in;width:100%}input::-webkit-input-placeholder{color:#adadad}input:-moz-placeholder,input::-moz-placeholder{color:#adadad}input:-ms-input-placeholder{color:#adadad}input:focus{border-color:#3ed778;box-shadow:none;outline:0 none}input.input-sm{height:30px}input.input-lg{height:50px}input.error{background-color:#ffeff4;border-color:#ff3c7e}input.valid{background-color:#ebfaeb;border-color:#37c936;color:#278d26}.showErrors{border-color:#ff8000}"]
295
379
  },] }
@@ -298,6 +382,24 @@ EmailInputComponent.propDecorators = {
298
382
  placeholder: [{ type: Input }]
299
383
  };
300
384
 
385
+ class LoadingIndicatorComponent {
386
+ constructor() {
387
+ this.variant = '3dots';
388
+ this.size = 'medium';
389
+ }
390
+ }
391
+ LoadingIndicatorComponent.decorators = [
392
+ { type: Component, args: [{
393
+ selector: 'klp-form-loading-indicator',
394
+ template: "<div class=\"threeDots\" [class]=\"size\" *ngIf=\"variant === '3dots'\">\n\t<div></div>\n\t<div></div>\n\t<div></div>\n\t<div></div>\n</div>\n\n<div class=\"spinner\" [class]=\"size\" *ngIf=\"variant === 'spinner'\">\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 48 48\">\n\t\t<circle cx=\"24\" cy=\"4\" r=\"4\" fill=\"currentColor\" />\n\t\t<circle cx=\"12.19\" cy=\"7.86\" r=\"3.7\" fill=\"currentColor\" />\n\t\t<circle cx=\"5.02\" cy=\"17.68\" r=\"3.4\" fill=\"currentColor\" />\n\t\t<circle cx=\"5.02\" cy=\"30.32\" r=\"3.1\" fill=\"currentColor\" />\n\t\t<circle cx=\"12.19\" cy=\"40.14\" r=\"2.8\" fill=\"currentColor\" />\n\t\t<circle cx=\"24\" cy=\"44\" r=\"2.5\" fill=\"currentColor\" />\n\t\t<circle cx=\"35.81\" cy=\"40.14\" r=\"2.2\" fill=\"currentColor\" />\n\t\t<circle cx=\"42.98\" cy=\"30.32\" r=\"1.9\" fill=\"currentColor\" />\n\t\t<circle cx=\"42.98\" cy=\"17.68\" r=\"1.6\" fill=\"currentColor\" />\n\t\t<circle cx=\"35.81\" cy=\"7.86\" r=\"1.3\" fill=\"currentColor\" />\n\t</svg>\n</div>\n\n<div class=\"textInput\" *ngIf=\"variant === 'textInput'\">\n\t<input\n\t\tdisabled\n\t\ttype=\"text\"\n\t\tclass=\"form-control\"\n\t\tplaceholder=\"Loading...\"\n\t>\n</div>\n\n<div class=\"picker\" *ngIf=\"variant === 'picker'\">\n\t<input\n\t\tdisabled\n\t\ttype=\"text\"\n\t\tclass=\"form-control\"\n\t\tplaceholder=\"Loading...\"\n\t>\n\t<div class=\"chevronDown\"></div>\n</div>\n",
395
+ styles: [".threeDots,:host{display:block}.threeDots{height:var(--base);position:relative;width:calc(var(--base)*4)}.threeDots.tiny{--base:4px}.threeDots.small{--base:8px}.threeDots.medium{--base:12px}.threeDots.large{--base:18px}.threeDots.huge{--base:26px}.threeDots div{-webkit-animation-timing-function:cubic-bezier(0,1,1,0);animation-timing-function:cubic-bezier(0,1,1,0);background:#27bb5f;border-radius:50%;height:var(--base);position:absolute;top:0;width:var(--base)}.threeDots div:first-child{-webkit-animation:lds-ellipsis1 .6s infinite;animation:lds-ellipsis1 .6s infinite}.threeDots div:nth-child(2),.threeDots div:nth-child(3){-webkit-animation:lds-ellipsis2 .6s infinite;animation:lds-ellipsis2 .6s infinite}.threeDots div:nth-child(3){left:calc(var(--base)*1.5)}.threeDots div:nth-child(4){-webkit-animation:lds-ellipsis3 .6s infinite;animation:lds-ellipsis3 .6s infinite;left:calc(var(--base)*3)}@-webkit-keyframes lds-ellipsis1{0%{transform:scale(0)}to{transform:scale(1)}}@keyframes lds-ellipsis1{0%{transform:scale(0)}to{transform:scale(1)}}@-webkit-keyframes lds-ellipsis3{0%{transform:scale(1)}to{transform:scale(0)}}@keyframes lds-ellipsis3{0%{transform:scale(1)}to{transform:scale(0)}}@-webkit-keyframes lds-ellipsis2{0%{transform:translate(0)}to{transform:translate(150%)}}@keyframes lds-ellipsis2{0%{transform:translate(0)}to{transform:translate(150%)}}.spinner.tiny svg{height:1rem;width:1rem}.spinner.small svg{height:1.6rem;width:1.6rem}.spinner.medium svg{height:2.5rem;width:2.5rem}.spinner.large svg{height:3rem;width:3rem}.spinner.huge svg{height:4rem;width:4rem}.spinner svg{-moz-animation-duration:1.2s;-moz-animation-iteration-count:infinite;-moz-animation-name:rotate;-moz-animation-timing-function:linear;-moz-transition-property:-moz-transform;-webkit-animation-duration:1.2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:rotate;-webkit-animation-timing-function:linear;-webkit-transition-duration:1.2s;-webkit-transition-property:-webkit-transform;animation-duration:1.2s;animation-iteration-count:infinite;animation-name:rotate;animation-timing-function:linear;transition-property:transform}@-webkit-keyframes rotate{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.picker{position:relative}.picker .chevronDown{border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #888da8;height:0;position:absolute;right:23px;top:18px;width:0}"]
396
+ },] }
397
+ ];
398
+ LoadingIndicatorComponent.propDecorators = {
399
+ variant: [{ type: Input }],
400
+ size: [{ type: Input }]
401
+ };
402
+
301
403
  class NumberInputComponent extends ValueAccessorBase {
302
404
  }
303
405
  NumberInputComponent.decorators = [
@@ -313,38 +415,40 @@ NumberInputComponent.propDecorators = {
313
415
  };
314
416
 
315
417
  class PasswordFieldComponent extends ValueAccessorBase {
418
+ constructor() {
419
+ super(...arguments);
420
+ this.placeholder = 'Password';
421
+ }
316
422
  }
317
423
  PasswordFieldComponent.decorators = [
318
424
  { type: Component, args: [{
319
- selector: 'klp-password-field',
320
- template: "<input\n\ttype=\"password\"\n\tclass=\"form-control\"\n [ngClass]=\"{showErrors: isInErrorState()}\"\n\t[(ngModel)]=\"innerValue\"\n\t(input)=\"setInnerValueAndNotify($event.target.value)\"\n\tplaceholder=\"{{ 'Password' }}\"\n\t(blur)=\"touch()\"\n/>\n<!-- TODO: translate -->\n",
425
+ selector: 'klp-form-password-field',
426
+ template: "<input\n\ttype=\"password\"\n\tclass=\"form-control\"\n [ngClass]=\"{showErrors: isInErrorState()}\"\n\t[(ngModel)]=\"innerValue\"\n\t(input)=\"setInnerValueAndNotify($event.target.value)\"\n\t[placeholder]=\"placeholder\"\n\t(blur)=\"touch()\"\n/>\n",
321
427
  providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: PasswordFieldComponent, multi: true }],
322
428
  styles: [":host,input{display:block}input{-moz-transition:all .2s ease-in;-ms-transition:all .2s ease-in;-o-transition:all .2s ease-in;-webkit-transition:all .2s ease-in;border:1px solid #e6ecf5;border-radius:2px;box-shadow:none;color:#888da8;font-size:14px;height:42px;outline:none;padding:.375rem .625rem;transition:all .2s ease-in;width:100%}input::-webkit-input-placeholder{color:#adadad}input:-moz-placeholder,input::-moz-placeholder{color:#adadad}input:-ms-input-placeholder{color:#adadad}input:focus{border-color:#3ed778;box-shadow:none;outline:0 none}input.input-sm{height:30px}input.input-lg{height:50px}input.error{background-color:#ffeff4;border-color:#ff3c7e}input.valid{background-color:#ebfaeb;border-color:#37c936;color:#278d26}.showErrors{border-color:#ff8000}"]
323
429
  },] }
324
430
  ];
431
+ PasswordFieldComponent.propDecorators = {
432
+ placeholder: [{ type: Input }]
433
+ };
325
434
 
326
435
  class SelectComponent extends ValueAccessorBase {
327
436
  constructor(parent, controlContainer) {
328
437
  super(parent, controlContainer);
329
438
  this.parent = parent;
330
439
  this.controlContainer = controlContainer;
440
+ this.placeholder = 'Pick an option';
331
441
  this.multiple = false;
332
442
  this.clearable = true;
333
- }
334
- ngOnInit() {
335
- super.ngOnInit();
336
- if (!this.placeholder) {
337
- // this.placeholder = this.translate.instant(_('Pick an option'));
338
- this.placeholder = ('Pick an option');
339
- }
443
+ this.onSearch = new EventEmitter();
340
444
  }
341
445
  }
342
446
  SelectComponent.decorators = [
343
447
  { type: Component, args: [{
344
448
  selector: 'klp-form-select',
345
- template: "<ng-select\n\t[placeholder]=\"placeholder\"\n\tbindLabel=\"name\"\n\tbindValue=\"id\"\n\t[items]=\"options\"\n\t[clearable]=\"clearable\"\n\t[(ngModel)]=\"innerValue\"\n\t[ngClass]=\"{showErrors: isInErrorState()}\"\n\t(change)=\"setInnerValueAndNotify(innerValue)\"\n\t[multiple]=\"multiple\"\n\t[disabled]=\"disabled\"\n\t(blur)=\"touch()\"\n\t[dropdownPosition]=\"dropdownPosition\"\n\t[searchFn]=\"customSearchFn\"\n>\n\t<ng-template let-item=\"item\" ng-option-tmp>\n\t\t{{ item.name }}\n\t\t<div *ngIf=\"item.description\" class=\"dropdown-item-description\">\n\t\t\t{{ item.description }}\n\t\t</div>\n\t</ng-template>\n</ng-select>\n",
449
+ template: "<ng-select\n\t[placeholder]=\"placeholder\"\n\tbindLabel=\"name\"\n\tbindValue=\"id\"\n\t[items]=\"options\"\n\t[clearable]=\"clearable\"\n\t[(ngModel)]=\"innerValue\"\n\t[ngClass]=\"{showErrors: isInErrorState()}\"\n\t(change)=\"setInnerValueAndNotify(innerValue)\"\n\t[multiple]=\"multiple\"\n\t[disabled]=\"disabled\"\n\t(blur)=\"touch()\"\n\t(search)=\"onSearch.emit($event.term)\"\n\t[dropdownPosition]=\"dropdownPosition\"\n\t[searchFn]=\"customSearchFn\"\n>\n\t<ng-template let-item=\"item\" ng-option-tmp>\n\t\t{{ item.name }}\n\t\t<div *ngIf=\"item.description\" class=\"dropdown-item-description\">\n\t\t\t{{ item.description }}\n\t\t</div>\n\t</ng-template>\n</ng-select>\n",
346
450
  providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: SelectComponent, multi: true }],
347
- styles: [":host{display:block}.showErrors ::ng-deep .ng-select-container{border-color:#ff8000}:host ::ng-deep ng-select.ng-select .ng-select-container{color:#888da8}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container{background:#fff;border-color:#3ed778}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container:hover{box-shadow:none}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container .ng-arrow{border-color:transparent transparent #999;border-width:0 5px 5px;top:-2px}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container .ng-arrow:hover{border-color:transparent transparent #666}:host ::ng-deep .ng-select.ng-select-opened.ng-select-bottom>.ng-select-container{border-bottom-left-radius:0;border-bottom-right-radius:0}:host ::ng-deep .ng-select.ng-select-opened.ng-select-top>.ng-select-container{border-top-left-radius:0;border-top-right-radius:0}:host ::ng-deep .ng-select.ng-select-disabled>.ng-select-container{background-color:#f9f9f9}:host ::ng-deep .ng-select .ng-has-value .ng-placeholder{display:none}:host ::ng-deep .ng-select .ng-select-container{align-items:center;background-clip:padding-box;background-color:#fff;border:1px solid #e6ecf5;border-radius:4px;border-radius:2px;box-shadow:none;box-sizing:border-box;color:#888da8;display:flex;flex-direction:row;font-size:1rem;font-size:14px;line-height:1.5;margin:0;min-height:42px;outline:none;overflow:visible;padding:.375rem .75rem;transition-delay:0s;transition-duration:.2s;transition-property:all;transition-timing-function:ease-in;width:100%}:host ::ng-deep .ng-select .ng-select-container:hover{box-shadow:0 1px 0 rgba(0,0,0,.06)}:host ::ng-deep .ng-select .ng-select-container .ng-value-container{align-items:center;overflow:hidden;padding-left:10px}:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder{color:#aaa}:host ::ng-deep .ng-select.ng-select-single .ng-select-container{height:42px}:host ::ng-deep .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{left:0;padding-left:10px;padding-right:50px;top:5px}:host ::ng-deep .ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value{background-color:#f9f9f9;border:1px solid #e3e3e3}:host ::ng-deep .ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value .ng-value-label{padding:0 5px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container{padding-left:7px;padding-right:10px;padding-top:2px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{background-color:#e7faee;border:1px solid #93e8b3;border-radius:2px;display:flex;font-size:.9em;margin-bottom:5px;margin-right:5px;overflow:hidden}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled{background-color:#f9f9f9;border:1px solid #e3e3e3}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-label{padding-left:5px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-label{display:inline-block;overflow:hidden;padding:0 5px;text-overflow:ellipsis}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon{display:inline-block;padding:0 5px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon:hover{background-color:#93e8b3}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.left{border-right:1px solid #93e8b3}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.right{border-left:1px solid #c2e0ff}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input{padding-bottom:3px;padding-left:3px}:host ::ng-deep ng-select.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{padding-bottom:3px;padding-left:3px;position:static;top:5px}:host ::ng-deep .ng-select .ng-clear-wrapper{color:#999}:host ::ng-deep .ng-select .ng-clear-wrapper .ng-clear:hover{color:#ff3c7e}:host ::ng-deep .ng-select .ng-spinner-zone{padding-right:5px;padding-top:5px}:host ::ng-deep .ng-select .ng-arrow-wrapper{padding-right:5px;width:25px}:host ::ng-deep .ng-select .ng-arrow-wrapper:hover .ng-arrow{border-top-color:#666}:host ::ng-deep .ng-select .ng-arrow-wrapper .ng-arrow{border-color:#999 transparent transparent;border-style:solid;border-width:5px 5px 2.5px}:host ::ng-deep .ng-dropdown-panel{background-color:#fff;border:1px solid #3ed778;box-shadow:0 1px 0 rgba(0,0,0,.06)}:host ::ng-deep .ng-dropdown-panel.ng-select-bottom{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top-color:#e6e6e6;margin-top:-1px;top:100%}:host ::ng-deep .ng-dropdown-panel.ng-select-bottom .ng-dropdown-panel-items .ng-option:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px}:host ::ng-deep .ng-dropdown-panel.ng-select-top{border-bottom-color:#e6e6e6;border-top-left-radius:4px;border-top-right-radius:4px;bottom:100%;margin-bottom:-1px}:host ::ng-deep .ng-dropdown-panel.ng-select-top .ng-dropdown-panel-items .ng-option:first-child{border-top-left-radius:4px;border-top-right-radius:4px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-header{border-bottom:1px solid #ccc;padding:5px 7px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-footer{border-top:1px solid #ccc;padding:5px 7px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items{margin-bottom:1px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;color:rgba(0,0,0,.54);cursor:default;cursor:pointer;font-weight:500;padding:8px 10px;user-select:none}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-disabled{cursor:default}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked{background-color:#ebf5ff}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected{background-color:#f5faff;font-weight:600}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option{background-color:#fff;color:rgba(0,0,0,.87);padding:8px 10px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected{background-color:#e7faee;color:#333}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected .ng-option-label{font-weight:600}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background-color:#e7faee;color:#333}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{color:#ccc}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-child{padding-left:22px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label{font-size:80%;font-weight:400;padding-right:5px}:host ::ng-deep ng-select.ng-select .ng-select-container .ng-value-container{padding-left:0}:host ::ng-deep ng-select.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{color:#888da8;top:9px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option,:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-input>input{color:#888da8}:host ::ng-deep .ng-select.ng-select-auto-grow{max-width:inherit}:host ::ng-deep .ng-select.ng-select-auto-grow .ng-dropdown-panel{width:auto}"]
451
+ styles: [":host{display:block}.showErrors ::ng-deep .ng-select-container,:host.showErrors ::ng-deep .ng-select-container{border-color:#ff8000}:host ::ng-deep ng-select.ng-select .ng-select-container{color:#888da8}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container{background:#fff;border-color:#3ed778}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container:hover{box-shadow:none}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container .ng-arrow{border-color:transparent transparent #999;border-width:0 5px 5px;top:-2px}:host ::ng-deep .ng-select.ng-select-opened>.ng-select-container .ng-arrow:hover{border-color:transparent transparent #666}:host ::ng-deep .ng-select.ng-select-opened.ng-select-bottom>.ng-select-container{border-bottom-left-radius:0;border-bottom-right-radius:0}:host ::ng-deep .ng-select.ng-select-opened.ng-select-top>.ng-select-container{border-top-left-radius:0;border-top-right-radius:0}:host ::ng-deep .ng-select.ng-select-disabled>.ng-select-container{background-color:#f9f9f9}:host ::ng-deep .ng-select .ng-has-value .ng-placeholder{display:none}:host ::ng-deep .ng-select .ng-select-container{align-items:center;background-clip:padding-box;background-color:#fff;border:1px solid #e6ecf5;border-radius:4px;border-radius:2px;box-shadow:none;box-sizing:border-box;color:#888da8;display:flex;flex-direction:row;font-size:1rem;font-size:14px;line-height:1.5;margin:0;min-height:42px;outline:none;overflow:visible;padding:.375rem .75rem;transition-delay:0s;transition-duration:.2s;transition-property:all;transition-timing-function:ease-in;width:100%}:host ::ng-deep .ng-select .ng-select-container:hover{box-shadow:0 1px 0 rgba(0,0,0,.06)}:host ::ng-deep .ng-select .ng-select-container .ng-value-container{align-items:center;overflow:hidden;padding-left:10px}:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder{color:#aaa}:host ::ng-deep .ng-select.ng-select-single .ng-select-container{height:42px}:host ::ng-deep .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{left:0;padding-left:10px;padding-right:50px;top:5px}:host ::ng-deep .ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value{background-color:#f9f9f9;border:1px solid #e3e3e3}:host ::ng-deep .ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value .ng-value-label{padding:0 5px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container{padding-left:7px;padding-right:10px;padding-top:2px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{background-color:#e7faee;border:1px solid #93e8b3;border-radius:2px;display:flex;font-size:.9em;margin-bottom:5px;margin-right:5px;overflow:hidden}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled{background-color:#f9f9f9;border:1px solid #e3e3e3}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-label{padding-left:5px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-label{display:inline-block;overflow:hidden;padding:0 5px;text-overflow:ellipsis}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon{display:inline-block;padding:0 5px}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon:hover{background-color:#93e8b3}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.left{border-right:1px solid #93e8b3}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.right{border-left:1px solid #c2e0ff}:host ::ng-deep .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input{padding-bottom:3px;padding-left:3px}:host ::ng-deep ng-select.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{padding-bottom:3px;padding-left:3px;position:static;top:5px}:host ::ng-deep .ng-select .ng-clear-wrapper{color:#999}:host ::ng-deep .ng-select .ng-clear-wrapper .ng-clear:hover{color:#ff3c7e}:host ::ng-deep .ng-select .ng-spinner-zone{padding-right:5px;padding-top:5px}:host ::ng-deep .ng-select .ng-arrow-wrapper{padding-right:5px;width:25px}:host ::ng-deep .ng-select .ng-arrow-wrapper:hover .ng-arrow{border-top-color:#666}:host ::ng-deep .ng-select .ng-arrow-wrapper .ng-arrow{border-color:#999 transparent transparent;border-style:solid;border-width:5px 5px 2.5px}:host ::ng-deep .ng-dropdown-panel{background-color:#fff;border:1px solid #3ed778;box-shadow:0 1px 0 rgba(0,0,0,.06)}:host ::ng-deep .ng-dropdown-panel.ng-select-bottom{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top-color:#e6e6e6;margin-top:-1px;top:100%}:host ::ng-deep .ng-dropdown-panel.ng-select-bottom .ng-dropdown-panel-items .ng-option:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px}:host ::ng-deep .ng-dropdown-panel.ng-select-top{border-bottom-color:#e6e6e6;border-top-left-radius:4px;border-top-right-radius:4px;bottom:100%;margin-bottom:-1px}:host ::ng-deep .ng-dropdown-panel.ng-select-top .ng-dropdown-panel-items .ng-option:first-child{border-top-left-radius:4px;border-top-right-radius:4px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-header{border-bottom:1px solid #ccc;padding:5px 7px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-footer{border-top:1px solid #ccc;padding:5px 7px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items{margin-bottom:1px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;color:rgba(0,0,0,.54);cursor:default;cursor:pointer;font-weight:500;padding:8px 10px;user-select:none}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-disabled{cursor:default}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked{background-color:#ebf5ff}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected{background-color:#f5faff;font-weight:600}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option{background-color:#fff;color:rgba(0,0,0,.87);padding:8px 10px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected{background-color:#e7faee;color:#333}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected .ng-option-label{font-weight:600}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background-color:#e7faee;color:#333}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{color:#ccc}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-child{padding-left:22px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label{font-size:80%;font-weight:400;padding-right:5px}:host ::ng-deep ng-select.ng-select .ng-select-container .ng-value-container{padding-left:0}:host ::ng-deep ng-select.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{color:#888da8;top:9px}:host ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option,:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-input>input{color:#888da8}:host ::ng-deep .ng-select.ng-select-auto-grow{max-width:inherit}:host ::ng-deep .ng-select.ng-select-auto-grow .ng-dropdown-panel{width:auto}"]
348
452
  },] }
349
453
  ];
350
454
  SelectComponent.ctorParameters = () => [
@@ -357,7 +461,8 @@ SelectComponent.propDecorators = {
357
461
  multiple: [{ type: Input }],
358
462
  clearable: [{ type: Input }],
359
463
  dropdownPosition: [{ type: Input }],
360
- customSearchFn: [{ type: Input }]
464
+ customSearchFn: [{ type: Input }],
465
+ onSearch: [{ type: Output }]
361
466
  };
362
467
 
363
468
  class SortableItemsComponent extends ValueAccessorBase {
@@ -493,17 +598,27 @@ class FormSubmitButtonComponent {
493
598
  .trySubmit()
494
599
  .then((value) => {
495
600
  this.isLoading = true;
496
- this.submitCallback(value)
497
- .then(() => (this.isLoading = false))
498
- .catch(() => (this.isLoading = false));
601
+ const submitCallbackResult = this.submitCallback(value);
602
+ if (isNullOrUndefined(submitCallbackResult)) {
603
+ throw new Error('No promise is returned in your submit function.');
604
+ }
605
+ return submitCallbackResult.then(() => (this.isLoading = false)).catch((e) => {
606
+ this.isLoading = false;
607
+ throw e;
608
+ });
499
609
  })
500
- .catch(() => { }); // swallow the error, the framework will scroll to the field that needs attention
610
+ .catch((e) => {
611
+ if (e === invalidFieldsSymbol) {
612
+ return; // swallow the error, the framework will scroll to the field that needs attention
613
+ }
614
+ throw e;
615
+ });
501
616
  }
502
617
  }
503
618
  FormSubmitButtonComponent.decorators = [
504
619
  { type: Component, args: [{
505
620
  selector: 'klp-form-submit-button',
506
- template: "<klp-button\n\t\t[variant]=\"variant\"\n\t\t(click)=\"submitForm()\"\n\t\t[disabled]=\"isLoading\"\n\t\t[isLoading]=\"isLoading\"\n\t\t[fullWidth]=\"fullWidth\"\n\t\ttype=\"submit\"\n\t\t[ngClass]=\"fullWidth ? 'fullWidth' : ''\"\n\t>\n\t<ng-content></ng-content>\n</klp-button>\n",
621
+ template: "<klp-form-button\n\t\t[variant]=\"variant\"\n\t\t(click)=\"submitForm()\"\n\t\t[disabled]=\"isLoading\"\n\t\t[isLoading]=\"isLoading\"\n\t\t[fullWidth]=\"fullWidth\"\n\t\ttype=\"submit\"\n\t\t[ngClass]=\"fullWidth ? 'fullWidth' : ''\"\n\t>\n\t<ng-content></ng-content>\n</klp-form-button>\n",
507
622
  styles: [":host{display:inline-block}:host._fullWidth{display:block}.fullWidth{width:100%}"]
508
623
  },] }
509
624
  ];
@@ -518,60 +633,127 @@ FormSubmitButtonComponent.propDecorators = {
518
633
  _: [{ type: HostBinding, args: ['class._fullWidth',] }]
519
634
  };
520
635
 
521
- class ButtonComponent {
636
+ const invalidDateKey = '--invalid_date--';
637
+ function dateValidator(control) {
638
+ const invalid = control.value === invalidDateKey;
639
+ return invalid ? { date: control.value } : null;
640
+ }
641
+
642
+ const KLP_DATE_FORMATS = new InjectionToken('klp.form.date.formats');
643
+ function matDateFormatsFactory(component, dateFormats) {
644
+ var _a;
645
+ return (_a = dateFormats === null || dateFormats === void 0 ? void 0 : dateFormats(component.format)) !== null && _a !== void 0 ? _a : MAT_NATIVE_DATE_FORMATS;
646
+ }
647
+ class DatepickerComponent extends ValueAccessorBase {
522
648
  constructor() {
523
- this.variant = 'white';
524
- this.size = 'medium';
525
- this.fullWidth = false;
526
- this.hasBorder = true;
527
- this.disabled = false;
528
- this.isLoading = false;
529
- this.type = 'button';
649
+ super(...arguments);
650
+ this.minDate = undefined;
651
+ this.maxDate = undefined;
652
+ this.placeholder = 'Select date';
653
+ this.clearable = false;
654
+ this.minDateStartOfDay = undefined;
655
+ this.maxDateEndOfDay = undefined;
656
+ }
657
+ ngOnChanges(changes) {
658
+ if (changes.minDate) {
659
+ this.setMinDate(changes.minDate.currentValue);
660
+ }
661
+ if (changes.maxDate) {
662
+ this.setMaxDate(changes.maxDate.currentValue);
663
+ }
530
664
  }
531
- get _() {
532
- return this.fullWidth;
665
+ setMinDate(minDate) {
666
+ if (minDate) {
667
+ this.minDateStartOfDay = new Date(minDate);
668
+ this.minDateStartOfDay.setHours(0, 0, 0, 0);
669
+ }
670
+ else {
671
+ this.minDateStartOfDay = undefined;
672
+ }
533
673
  }
534
- onClick(event) {
535
- if (this.disabled) {
536
- event.stopPropagation();
674
+ setMaxDate(maxDate) {
675
+ if (maxDate) {
676
+ this.maxDateEndOfDay = new Date(maxDate);
677
+ this.maxDateEndOfDay.setHours(23, 59, 59, 999);
678
+ }
679
+ else {
680
+ this.maxDateEndOfDay = undefined;
537
681
  }
538
682
  }
683
+ // dateChanged is called when the output of the datepicker is changed and
684
+ // parsed correctly. If the date is invalid, it will be called the first time
685
+ // with null but never again until a valid input is provided.
686
+ dateChanged(event) {
687
+ const nativeInputValue = this.nativeInputRef.nativeElement.value;
688
+ const date = event.value;
689
+ if (isNullOrUndefined(date) && stringIsSetAndNotEmpty(nativeInputValue)) {
690
+ this.setInnerValueAndNotify(invalidDateKey);
691
+ }
692
+ else {
693
+ this.setInnerValueAndNotify(date);
694
+ }
695
+ }
696
+ writeValue(value) {
697
+ super.writeValue(value);
698
+ this.valueForMaterialDatePicker = value === invalidDateKey ? null : value;
699
+ }
700
+ // nativeValueChanged is called when the internal text value changes, but not
701
+ // when the date is changed via the date picker. We need this so that we can
702
+ // determine if the datepicker is empty or invalid.
703
+ nativeValueChanged(event) {
704
+ const nativeInputValue = event.target.value;
705
+ const date = this.valueForMaterialDatePicker;
706
+ if (this.datePickerRef.opened) {
707
+ // if the user is typing instead of using the picker, close it.
708
+ this.datePickerRef.close();
709
+ }
710
+ if (isNullOrUndefined(date) && stringIsSetAndNotEmpty(nativeInputValue)) {
711
+ this.setInnerValueAndNotify(invalidDateKey);
712
+ }
713
+ else {
714
+ this.setInnerValueAndNotify(date);
715
+ }
716
+ }
717
+ resetToNull() {
718
+ this.setInnerValueAndNotify(null);
719
+ this.valueForMaterialDatePicker = null;
720
+ this.nativeInputRef.nativeElement.value = null;
721
+ }
539
722
  }
540
- ButtonComponent.decorators = [
723
+ DatepickerComponent.decorators = [
541
724
  { type: Component, args: [{
542
- selector: 'klp-button',
543
- template: "<button class=\"buttonFundamentals\"\n\t[ngClass]=\"[\n\t\tvariant,\n\t\tsize,\n\t\tfullWidth ? 'fullWidth' : '',\n\t\thasBorder ? '' : 'no-border',\n\t\tdisabled ? 'disabled' : ''\n\t]\"\n\t[type]=\"type\"\n\t(click)=\"onClick($event)\"\n>\n\t<div class=\"caption\" [ngClass]=\"{invisible: isLoading}\">\n\t\t<ng-content></ng-content>\n\t</div>\n\t<div class=\"loadingSpinnerContainer\" *ngIf=\"isLoading\">\n\t\t<klp-loading-indicator variant=\"spinner\" size=\"small\"></klp-loading-indicator>\n\t</div>\n</button>\n",
544
- styles: [":host{display:inline-block}:host._fullWidth{display:block}.buttonFundamentals{border:1px solid #e6ecf5;border-radius:5px;color:#888da8;cursor:pointer;font-size:13px;font-weight:700;letter-spacing:1px;padding:10px 20px}.fullWidth{width:100%}.no-border{border:none}.caption.invisible{visibility:hidden}button{position:relative}.loadingSpinnerContainer{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0}.small{padding-bottom:.375rem;padding-top:.375rem}.large{line-height:2}.white{background-color:#fff;border-color:#d4deee;color:#515365;font-weight:500}.white:active,.white:hover{background-color:#edf2f8;border-color:#edf2f8;color:#515365}.white:focus{text-decoration:underline}.greenFilled{background-color:#27bb5f;border-color:#27bb5f;color:#fff}.greenFilled:hover{background-color:#2bd06a;border-color:#2bd06a;color:#fff}.greenFilled:focus{text-decoration:underline}.greenFilled:active{background-color:#23a654;border-color:#23a654}.greenOutlined{background-color:#fff;border-color:#27bb5f;color:#27bb5f}.greenOutlined:hover{background-color:#2bd06a;border-color:#2bd06a;color:#fff}.greenOutlined:focus{text-decoration:underline}.greenOutlined:active{background-color:#23a654;border-color:#23a654}.greenLink{background:none;border:none;color:#27bb5f;padding:0}.greenLink:focus,.greenLink:hover{text-decoration:underline}.contextMenuItem{background-color:#fff;border-color:#fff;color:#888da8}.contextMenuItem:hover{background-color:#f6f7fb;border-color:#f6f7fb}.contextMenuItem:active,.contextMenuItem:focus{text-decoration:underline}.redFilled{background-color:#ff3c7e;border-color:#ff3c7e;color:#fff}.redFilled:hover{background-color:#ff568f;border-color:#ff568f;color:#fff}.redFilled:focus{text-decoration:underline}.redFilled:active{background-color:#ff236d;border-color:#ff236d}.redOutlined{background-color:#fff;border-color:#ff3c7e;color:#ff3c7e}.redOutlined:hover{background-color:#ff568f;border-color:#ff568f;color:#fff}.redOutlined:focus{text-decoration:underline}.redOutlined:active{background-color:#ff236d;border-color:#ff236d}.orangeFilled{background-color:#ff8000;border-color:#ff8000;color:#fff}.orangeFilled:hover{background-color:#ff8d1a;border-color:#ff8d1a;color:#fff}.orangeFilled:focus{text-decoration:underline}.orangeFilled:active{background-color:#e67300;border-color:#e67300}"]
725
+ selector: 'klp-form-datepicker',
726
+ template: "<div class=\"componentContainer\" [ngClass]=\"{showErrors: isInErrorState()}\">\n\t<mat-form-field [floatLabel]=\"'never'\">\n\t\t<input\n\t\t\t#nativeInput\n\t\t\tmatInput\n\t\t\t[matDatepicker]=\"picker\"\n\t\t\t[(ngModel)]=\"valueForMaterialDatePicker\"\n\t\t\t(dateInput)=\"dateChanged($event)\"\n\t\t\t(input)=\"nativeValueChanged($event)\"\n\t\t\t[min]=\"minDateStartOfDay\"\n\t\t\t[max]=\"maxDateEndOfDay\"\n\t\t\t[placeholder]=\"placeholder\"\n\t\t\t(click)=\"picker.open()\"\n\t\t\t(blur)=\"touch()\"\n\t\t>\n\t\t<mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n\t\t<mat-datepicker #picker\n\t\t></mat-datepicker>\n\t</mat-form-field>\n\t<button *ngIf=\"clearable\" class=\"clearButton\" (click)=\"resetToNull()\">\u00D7</button>\n</div>\n",
727
+ providers: [
728
+ { provide: NG_VALUE_ACCESSOR, useExisting: DatepickerComponent, multi: true },
729
+ { provide: MAT_DATE_FORMATS,
730
+ deps: [DatepickerComponent, [new Optional(), KLP_DATE_FORMATS]],
731
+ useFactory: matDateFormatsFactory,
732
+ }
733
+ ],
734
+ styles: [":host{display:block}:host ::ng-deep mat-form-field{display:block;height:100%}:host ::ng-deep mat-form-field.mat-focused .mat-form-field-label,:host ::ng-deep mat-form-field .mat-form-field-label{color:#adadad}:host ::ng-deep .mat-datepicker-toggle-active{color:#666}:host ::ng-deep .mat-form-field-wrapper{padding-bottom:none}:host ::ng-deep .mat-form-field-flex{flex-direction:row-reverse}:host ::ng-deep .mat-form-field-infix{border-top:none}:host ::ng-deep .mat-form-field-suffix{margin-right:.625rem}:host ::ng-deep .mat-form-field-suffix:hover .mat-button-focus-overlay{opacity:.1}:host ::ng-deep .mat-form-field-underline{display:none}.componentContainer{-moz-transition:all .2s ease-in;-ms-transition:all .2s ease-in;-o-transition:all .2s ease-in;-webkit-transition:all .2s ease-in;border:1px solid #e6ecf5;border-radius:2px;box-shadow:none;color:#888da8;display:block;font-size:14px;height:42px;padding:.375rem .625rem;position:relative;transition:all .2s ease-in;width:100%}.componentContainer::-webkit-input-placeholder{color:#adadad}.componentContainer:-moz-placeholder,.componentContainer::-moz-placeholder{color:#adadad}.componentContainer:-ms-input-placeholder{color:#adadad}.componentContainer:focus{border-color:#3ed778;box-shadow:none;outline:0 none}.componentContainer.input-sm{height:30px}.componentContainer.input-lg{height:50px}.componentContainer.error{background-color:#ffeff4;border-color:#ff3c7e}.componentContainer.valid{background-color:#ebfaeb;border-color:#37c936;color:#278d26}.componentContainer.showErrors{border-color:#ff8000}.componentContainer .clearButton{align-items:center;background:none;border:none;bottom:0;color:#7b7b7b;display:flex;font-size:18px;position:absolute;right:1.25rem;top:0}"]
545
735
  },] }
546
736
  ];
547
- ButtonComponent.propDecorators = {
548
- variant: [{ type: Input }],
549
- size: [{ type: Input }],
550
- fullWidth: [{ type: Input }],
551
- hasBorder: [{ type: Input }],
552
- disabled: [{ type: Input }],
553
- isLoading: [{ type: Input }],
554
- type: [{ type: Input }],
555
- _: [{ type: HostBinding, args: ['class._fullWidth',] }]
737
+ DatepickerComponent.propDecorators = {
738
+ minDate: [{ type: Input }],
739
+ maxDate: [{ type: Input }],
740
+ format: [{ type: Input }],
741
+ placeholder: [{ type: Input }],
742
+ clearable: [{ type: Input }],
743
+ nativeInputRef: [{ type: ViewChild, args: ['nativeInput',] }],
744
+ datePickerRef: [{ type: ViewChild, args: ['picker',] }]
556
745
  };
557
746
 
558
- class LoadingIndicatorComponent {
559
- constructor() {
560
- this.variant = '3dots';
561
- this.size = 'medium';
562
- }
747
+ // material.module.ts
748
+ class MaterialModule {
563
749
  }
564
- LoadingIndicatorComponent.decorators = [
565
- { type: Component, args: [{
566
- selector: 'klp-loading-indicator',
567
- template: "<div class=\"threeDots\" [class]=\"size\" *ngIf=\"variant === '3dots'\">\n\t<div></div>\n\t<div></div>\n\t<div></div>\n\t<div></div>\n</div>\n\n<div class=\"spinner\" [class]=\"size\" *ngIf=\"variant === 'spinner'\">\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 48 48\">\n\t\t<circle cx=\"24\" cy=\"4\" r=\"4\" fill=\"currentColor\" />\n\t\t<circle cx=\"12.19\" cy=\"7.86\" r=\"3.7\" fill=\"currentColor\" />\n\t\t<circle cx=\"5.02\" cy=\"17.68\" r=\"3.4\" fill=\"currentColor\" />\n\t\t<circle cx=\"5.02\" cy=\"30.32\" r=\"3.1\" fill=\"currentColor\" />\n\t\t<circle cx=\"12.19\" cy=\"40.14\" r=\"2.8\" fill=\"currentColor\" />\n\t\t<circle cx=\"24\" cy=\"44\" r=\"2.5\" fill=\"currentColor\" />\n\t\t<circle cx=\"35.81\" cy=\"40.14\" r=\"2.2\" fill=\"currentColor\" />\n\t\t<circle cx=\"42.98\" cy=\"30.32\" r=\"1.9\" fill=\"currentColor\" />\n\t\t<circle cx=\"42.98\" cy=\"17.68\" r=\"1.6\" fill=\"currentColor\" />\n\t\t<circle cx=\"35.81\" cy=\"7.86\" r=\"1.3\" fill=\"currentColor\" />\n\t</svg>\n</div>\n\n<div class=\"textInput\" *ngIf=\"variant === 'textInput'\">\n\t<input\n\t\tdisabled\n\t\ttype=\"text\"\n\t\tclass=\"form-control\"\n\t\tplaceholder=\"Loading...\"\n\t>\n</div>\n\n<div class=\"picker\" *ngIf=\"variant === 'picker'\">\n\t<input\n\t\tdisabled\n\t\ttype=\"text\"\n\t\tclass=\"form-control\"\n\t\tplaceholder=\"Loading...\"\n\t>\n\t<div class=\"chevronDown\"></div>\n</div>\n",
568
- styles: [".threeDots,:host{display:block}.threeDots{height:var(--base);position:relative;width:calc(var(--base)*4)}.threeDots.tiny{--base:4px}.threeDots.small{--base:8px}.threeDots.medium{--base:12px}.threeDots.large{--base:18px}.threeDots.huge{--base:26px}.threeDots div{-webkit-animation-timing-function:cubic-bezier(0,1,1,0);animation-timing-function:cubic-bezier(0,1,1,0);background:#27bb5f;border-radius:50%;height:var(--base);position:absolute;top:0;width:var(--base)}.threeDots div:first-child{-webkit-animation:lds-ellipsis1 .6s infinite;animation:lds-ellipsis1 .6s infinite}.threeDots div:nth-child(2),.threeDots div:nth-child(3){-webkit-animation:lds-ellipsis2 .6s infinite;animation:lds-ellipsis2 .6s infinite}.threeDots div:nth-child(3){left:calc(var(--base)*1.5)}.threeDots div:nth-child(4){-webkit-animation:lds-ellipsis3 .6s infinite;animation:lds-ellipsis3 .6s infinite;left:calc(var(--base)*3)}@-webkit-keyframes lds-ellipsis1{0%{transform:scale(0)}to{transform:scale(1)}}@keyframes lds-ellipsis1{0%{transform:scale(0)}to{transform:scale(1)}}@-webkit-keyframes lds-ellipsis3{0%{transform:scale(1)}to{transform:scale(0)}}@keyframes lds-ellipsis3{0%{transform:scale(1)}to{transform:scale(0)}}@-webkit-keyframes lds-ellipsis2{0%{transform:translate(0)}to{transform:translate(150%)}}@keyframes lds-ellipsis2{0%{transform:translate(0)}to{transform:translate(150%)}}.spinner.tiny svg{height:1rem;width:1rem}.spinner.small svg{height:1.6rem;width:1.6rem}.spinner.medium svg{height:2.5rem;width:2.5rem}.spinner.large svg{height:3rem;width:3rem}.spinner.huge svg{height:4rem;width:4rem}.spinner svg{-moz-animation-duration:1.2s;-moz-animation-iteration-count:infinite;-moz-animation-name:rotate;-moz-animation-timing-function:linear;-moz-transition-property:-moz-transform;-webkit-animation-duration:1.2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:rotate;-webkit-animation-timing-function:linear;-webkit-transition-duration:1.2s;-webkit-transition-property:-webkit-transform;animation-duration:1.2s;animation-iteration-count:infinite;animation-name:rotate;animation-timing-function:linear;transition-property:transform}@-webkit-keyframes rotate{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.picker{position:relative}.picker .chevronDown{border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #888da8;height:0;position:absolute;right:23px;top:18px;width:0}"]
750
+ MaterialModule.decorators = [
751
+ { type: NgModule, args: [{
752
+ imports: [MatDatepickerModule, MatFormFieldModule, MatNativeDateModule, MatInputModule, MatButtonModule],
753
+ exports: [MatDatepickerModule, MatFormFieldModule, MatNativeDateModule, MatInputModule, MatButtonModule],
754
+ providers: [MatDatepickerModule],
569
755
  },] }
570
756
  ];
571
- LoadingIndicatorComponent.propDecorators = {
572
- variant: [{ type: Input }],
573
- size: [{ type: Input }]
574
- };
575
757
 
576
758
  class NgxEnhancyFormsModule {
577
759
  }
@@ -582,11 +764,13 @@ NgxEnhancyFormsModule.decorators = [
582
764
  FormsModule,
583
765
  NgSelectModule,
584
766
  SortablejsModule,
767
+ MaterialModule,
585
768
  ],
586
769
  declarations: [
587
770
  ValueAccessorBase,
588
771
  ButtonComponent,
589
772
  CheckboxComponent,
773
+ DatepickerComponent,
590
774
  EmailInputComponent,
591
775
  LoadingIndicatorComponent,
592
776
  NumberInputComponent,
@@ -604,6 +788,7 @@ NgxEnhancyFormsModule.decorators = [
604
788
  exports: [
605
789
  ValueAccessorBase,
606
790
  ButtonComponent,
791
+ DatepickerComponent,
607
792
  CheckboxComponent,
608
793
  EmailInputComponent,
609
794
  LoadingIndicatorComponent,
@@ -630,5 +815,5 @@ NgxEnhancyFormsModule.decorators = [
630
815
  * Generated bundle index. Do not edit.
631
816
  */
632
817
 
633
- export { NgxEnhancyFormsModule, ValueAccessorBase as ɵa, FormElementComponent as ɵb, FormComponent as ɵc, ButtonComponent as ɵd, CheckboxComponent as ɵe, EmailInputComponent as ɵf, LoadingIndicatorComponent as ɵg, NumberInputComponent as ɵh, PasswordFieldComponent as ɵi, SelectComponent as ɵj, SortableItemsComponent as ɵk, TextInputComponent as ɵl, ToggleComponent as ɵm, FormCaptionComponent as ɵn, FormErrorComponent as ɵo, FormSubmitButtonComponent as ɵp };
818
+ export { ButtonComponent, CheckboxComponent, DEFAULT_ERROR_MESSAGES, DatepickerComponent, EmailInputComponent, FORM_ERROR_MESSAGES, FormCaptionComponent, FormComponent, FormElementComponent, FormErrorComponent, FormSubmitButtonComponent, KLP_DATE_FORMATS, LoadingIndicatorComponent, NgxEnhancyFormsModule, NumberInputComponent, PasswordFieldComponent, SelectComponent, SortableItemsComponent, TextInputComponent, ToggleComponent, ValueAccessorBase, dateValidator, invalidDateKey, invalidFieldsSymbol, matDateFormatsFactory, MaterialModule as ɵa };
634
819
  //# sourceMappingURL=klippa-ngx-enhancy-forms.js.map