hr-design-system-handlebars 1.100.2 → 1.100.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/assets/index.css +36 -3
  3. package/dist/views/components/forms/fields.hbs +5 -3
  4. package/dist/views/components/forms/input_single_line.hbs +60 -14
  5. package/dist/views/components/forms/textarea.hbs +77 -0
  6. package/dist/views_static/components/forms/fields.hbs +5 -3
  7. package/dist/views_static/components/forms/input_single_line.hbs +60 -14
  8. package/dist/views_static/components/forms/textarea.hbs +77 -0
  9. package/package.json +1 -1
  10. package/src/assets/fixtures/content/copytext/copytext_webform.json +1 -1
  11. package/src/assets/fixtures/forms/form_email.json +9 -0
  12. package/src/assets/fixtures/forms/form_fields.inc.json +35 -3
  13. package/src/assets/fixtures/forms/form_input.json +0 -8
  14. package/src/assets/fixtures/forms/form_input_mandatory.json +8 -0
  15. package/src/assets/fixtures/forms/form_input_prefilled.json +8 -0
  16. package/src/assets/fixtures/forms/form_textarea.json +18 -0
  17. package/src/stories/views/components/content/copytext/fixtures/copytext_webform.json +1 -1
  18. package/src/stories/views/components/forms/fields.hbs +5 -3
  19. package/src/stories/views/components/forms/fixtures/form_email.json +1 -0
  20. package/src/stories/views/components/forms/fixtures/form_input.json +1 -1
  21. package/src/stories/views/components/forms/fixtures/form_input_mandatory.json +1 -0
  22. package/src/stories/views/components/forms/fixtures/form_input_prefilled.json +1 -0
  23. package/src/stories/views/components/forms/fixtures/form_textarea.json +1 -0
  24. package/src/stories/views/components/forms/form.stories.js +41 -7
  25. package/src/stories/views/components/forms/input_single_line.hbs +60 -14
  26. package/src/stories/views/components/forms/textarea.hbs +77 -0
  27. package/tailwind.config.js +3 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ # v1.100.4 (Fri Sep 13 2024)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - ✨ Email field - DPE 3292 [#1065](https://github.com/mumprod/hr-design-system-handlebars/pull/1065) ([@vascoeduardo](https://github.com/vascoeduardo))
6
+
7
+ #### Authors: 1
8
+
9
+ - Vasco ([@vascoeduardo](https://github.com/vascoeduardo))
10
+
11
+ ---
12
+
13
+ # v1.100.3 (Wed Sep 11 2024)
14
+
15
+ #### 🐛 Bug Fix
16
+
17
+ - ✨ Mehrzeiliges Textfeld [#1064](https://github.com/mumprod/hr-design-system-handlebars/pull/1064) ([@vascoeduardo](https://github.com/vascoeduardo))
18
+
19
+ #### Authors: 1
20
+
21
+ - Vasco ([@vascoeduardo](https://github.com/vascoeduardo))
22
+
23
+ ---
24
+
1
25
  # v1.100.2 (Tue Sep 10 2024)
2
26
 
3
27
  #### 🐛 Bug Fix
@@ -1136,6 +1136,9 @@ article.indexTextDS .indexTextHighlighted .link {
1136
1136
  .right-0 {
1137
1137
  right: 0px;
1138
1138
  }
1139
+ .right-4 {
1140
+ right: 1rem;
1141
+ }
1139
1142
  .right-\[50px\] {
1140
1143
  right: 50px;
1141
1144
  }
@@ -1700,6 +1703,9 @@ article.indexTextDS .indexTextHighlighted .link {
1700
1703
  .max-h-stage {
1701
1704
  max-height: 34.3125rem;
1702
1705
  }
1706
+ .min-h-12 {
1707
+ min-height: 3rem;
1708
+ }
1703
1709
  .min-h-\[88px\] {
1704
1710
  min-height: 88px;
1705
1711
  }
@@ -2342,6 +2348,14 @@ article.indexTextDS .indexTextHighlighted .link {
2342
2348
  border-color: #005293;
2343
2349
  border-color: var(--color-primary-ds);
2344
2350
  }
2351
+ .border-red-500 {
2352
+ --tw-border-opacity: 1;
2353
+ border-color: rgba(239, 68, 68, var(--tw-border-opacity));
2354
+ }
2355
+ .border-red-700 {
2356
+ --tw-border-opacity: 1;
2357
+ border-color: rgba(185, 28, 28, var(--tw-border-opacity));
2358
+ }
2345
2359
  .border-servicenavigation-border-color {
2346
2360
  border-color: #fff;
2347
2361
  border-color: var(--color-servicenavigation-border-color);
@@ -2636,6 +2650,9 @@ article.indexTextDS .indexTextHighlighted .link {
2636
2650
  fill: #006eb7;
2637
2651
  fill: var(--color-link);
2638
2652
  }
2653
+ .fill-red-700 {
2654
+ fill: #b91c1c;
2655
+ }
2639
2656
  .fill-search {
2640
2657
  fill: #000000;
2641
2658
  fill: var(--search-icon-color);
@@ -2813,6 +2830,9 @@ article.indexTextDS .indexTextHighlighted .link {
2813
2830
  padding-bottom: 16px;
2814
2831
  padding-bottom: var(--footer-padding-bottom);
2815
2832
  }
2833
+ .pb-px {
2834
+ padding-bottom: 1px;
2835
+ }
2816
2836
  .pl-10 {
2817
2837
  padding-left: 2.5rem;
2818
2838
  }
@@ -2855,6 +2875,9 @@ article.indexTextDS .indexTextHighlighted .link {
2855
2875
  .pr-8 {
2856
2876
  padding-right: 2rem;
2857
2877
  }
2878
+ .pr-9 {
2879
+ padding-right: 2.25rem;
2880
+ }
2858
2881
  .pt-0 {
2859
2882
  padding-top: 0px;
2860
2883
  }
@@ -3408,7 +3431,7 @@ article.indexTextDS .indexTextHighlighted .link {
3408
3431
  border-bottom-color: var(--color-secondary-ds);
3409
3432
  }
3410
3433
  .counter-reset {
3411
- counter-reset: cnt1725971545380;
3434
+ counter-reset: cnt1726216106674;
3412
3435
  }
3413
3436
  .hyphens-auto {
3414
3437
  -webkit-hyphens: auto;
@@ -3816,7 +3839,7 @@ article.indexTextDS .indexTextHighlighted .link {
3816
3839
  --tw-ring-color: rgba(255, 255, 255, 0.5);
3817
3840
  }
3818
3841
  .-ordered {
3819
- counter-increment: cnt1725971545380 1;
3842
+ counter-increment: cnt1726216106674 1;
3820
3843
  }
3821
3844
  .-ordered::before {
3822
3845
  position: absolute;
@@ -3832,7 +3855,7 @@ article.indexTextDS .indexTextHighlighted .link {
3832
3855
  letter-spacing: .0125em;
3833
3856
  --tw-text-opacity: 1;
3834
3857
  color: rgba(0, 0, 0, var(--tw-text-opacity));
3835
- content: counter(cnt1725971545380);
3858
+ content: counter(cnt1726216106674);
3836
3859
  }
3837
3860
  /*! ****************************/
3838
3861
  /*! DataPolicy stuff */
@@ -5775,10 +5798,20 @@ ul.restrictedToTwo li:nth-of-type(1n + 2) .timelineBorder {
5775
5798
  .hover\:\!decoration-1:hover {
5776
5799
  text-decoration-thickness: 1px !important;
5777
5800
  }
5801
+ .focus\:border-y-2:focus {
5802
+ border-top-width: 2px;
5803
+ border-bottom-width: 2px;
5804
+ }
5805
+ .focus\:border-b-2:focus {
5806
+ border-bottom-width: 2px;
5807
+ }
5778
5808
  .focus\:bg-black:focus {
5779
5809
  --tw-bg-opacity: 1;
5780
5810
  background-color: rgba(0, 0, 0, var(--tw-bg-opacity));
5781
5811
  }
5812
+ .focus\:pb-0:focus {
5813
+ padding-bottom: 0px;
5814
+ }
5782
5815
  .focus\:text-white:focus {
5783
5816
  --tw-text-opacity: 1;
5784
5817
  color: rgba(255, 255, 255, var(--tw-text-opacity));
@@ -18,10 +18,9 @@
18
18
 
19
19
  <div class="c-form__row js-wrapper-{{this.name}}">
20
20
  {{#if this.type.isTextarea}}
21
- {{~> modules/forms/textarea
21
+ {{~> components/forms/textarea
22
22
  _name=this.name
23
23
  _label=this.label
24
- _labelClass="hide"
25
24
  _description=this.description
26
25
  _defaultValue=this.defaultValue
27
26
  _counter=this.counter
@@ -29,10 +28,12 @@
29
28
  _cols=this.columns
30
29
  _required=this.isRequired
31
30
  _maxLength=this.maxLength
31
+ _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
32
32
  }}
33
33
  {{else if this.type.isText}}
34
34
  {{~> components/forms/input_single_line
35
35
  _type=this.type.asString
36
+ _isEmail=this.type.isEmail
36
37
  _name=this.name
37
38
  _label=this.label
38
39
  _labelClass="hide"
@@ -42,7 +43,8 @@
42
43
  _tabindex=(if this.isHidden "-1")
43
44
  _required=this.isRequired
44
45
  _maxLength=this.maxLength
45
- _errorMessage="Bitte füllen Sie diese Pflichtfeld aus"
46
+ _errorMandatory="Bitte füllen Sie dieses Pflichtfeld aus"
47
+ _errorEmail="Bitte geben Sie eine gültige E-Mail-Adresse ein."
46
48
  }}
47
49
  {{else if this.type.isSelect}}
48
50
  {{~> modules/forms/select
@@ -1,10 +1,13 @@
1
- <div class="relative flex flex-col w-full mb-5" x-data="{ input{{nextRandom}}: '' , valid: false, wasFocused: false}">
2
- <input class="relative w-full h-12 px-4 pt-4 text-gray-800 placeholder-transparent bg-white border-blue-500 peer border-y border-t-transparent focus:outline-none"
3
- x-model="input{{getRandom}}"
1
+ <div class="relative flex flex-col w-full mb-5"
2
+ x-data="inputHandler">
3
+ <input class="relative w-full h-12 pt-4 pl-4 text-gray-800 placeholder-transparent bg-white border-blue-500 pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
4
+ :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
5
+ x-model="input{{nextRandom}}"
4
6
  id="input{{getRandom}}"
5
7
  {{#if _required}}
6
- @blur="wasFocused = true;"
7
- x-on:keyup ="input{{getRandom}}.length > 0 ? valid = true : valid = false"
8
+ @focus="isFocused = true"
9
+ @blur="wasFocused = true; isFocused=false"
10
+ x-on:keyup ="input{{getRandom}}.length > 0 ? valid = true : valid = false; validateEmail()"
8
11
  {{/if}}
9
12
  type="{{#if _type}}{{_type}}{{/if}}"
10
13
  name="{{#if _name}}{{_name}}{{/if}}"
@@ -35,12 +38,7 @@
35
38
  {{#if _autoSuggestFeature}}
36
39
  data-hr-search-suggest='{"templateUrl":"{{resourceUrl "suche/index~suggest.jsp"}}"}'{{/if}}
37
40
  >
38
- <div class="hidden">
39
- <div>DEBUGG</div>
40
- <div>wasFocused:<span x-text="wasFocused"></span></div>
41
- <div>valid:<span x-text="valid"></span></div>
42
- <div>input.length:<span x-text="input{{getRandom}}.length "></span></div>
43
- </div>
41
+
44
42
  <label for="input{{getRandom}}" class="absolute left-[16px] top-px translate-y-0 translate-x-0 scale-75 text-gray-500
45
43
 
46
44
  peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-x-0 peer-placeholder-shown:translate-y-3
@@ -58,15 +56,63 @@
58
56
  {{/if}}
59
57
  {{/if}}
60
58
  </label>
59
+ {{#if _required}}
60
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
61
+ <div class="hidden w-5 h-5 font-bold" :class="{'hidden': hideError() }">
62
+ {{> components/base/image/icon _icon="info2" _addClass="w-5 h-5 fill-red-700"}}
63
+ </div>
64
+ </div>
65
+ {{/if}}
61
66
  <div class="flex items-end justify-between h-5 font-heading">
62
67
  {{#if _description}}
63
- <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused}"{{/if}}>{{_description}}</div>
68
+ <div class="pl-4 text-xs text-gray-500" {{#if _required}}:class="{'hidden': hideDescription() }"{{/if}}>{{_description}}</div>
64
69
  {{/if}}
65
70
  {{#if _required}}
66
- <div class="hidden pl-4 text-xs font-bold text-red-700" :class="{'hidden': valid || !wasFocused }" >{{_errorMessage}}</div>
71
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': hideError()}" x-text="errorMessage"></div>
67
72
  {{/if}}
68
73
  {{#if _maxLength}}
69
74
  <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="input{{getRandom}}.length">0</span>/{{_maxLength}}</div>
70
75
  {{/if~}}
71
76
  </div>
72
- </div>
77
+ <div class="hidden">
78
+ <b>DEBUGG</b>
79
+ <div>isFocused:<span x-text="isFocused"></span></div>
80
+ <div>wasFocused:<span x-text="wasFocused"></span></div>
81
+ <div>valid:<span x-text="valid"></span></div>
82
+ <div>validEmail:<span x-text="validEmail"></span></div>
83
+ <div>hideDescription:<span x-text="hideDescription"></span></div>
84
+ <div>hideError:<span x-text="hideError"></span></div>
85
+ <div>input.length:<span x-text="input{{getRandom}}.length "></span></div>
86
+ <div>input:<span x-text="input{{getRandom}} "></span></div>
87
+ <div>errorMessage:<span x-text="errorMessage"></span></div>
88
+ </div>
89
+ <script>
90
+ function inputHandler() {
91
+ return {
92
+ input{{getRandom}}: '{{#if _formField.forHtmlAttribute}}{{_formField.forHtmlAttribute}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}' ,
93
+ valid: false,
94
+ wasFocused: false,
95
+ isFocused: false,
96
+ {{#if _isEmail}}
97
+ validEmail: false,
98
+ errorMessage(){ return !this.valid ? '{{_errorMandatory}}' : '{{_errorEmail}}'},
99
+ hideDescription() {return (!this.valid && this.wasFocused && !this.isFocused) || (!this.validEmail && this.wasFocused && !this.isFocused)},
100
+ hideError() {return !this.hideDescription()},
101
+
102
+ validateEmail() {
103
+ var email = this.input{{getRandom}}
104
+ var emailRegex = /^[a-zA-Z0–9._-]+@[a-zA-Z0–9.-]+\.[a-zA-Z]{2,4}$/;
105
+ this.validEmail = emailRegex.test(email);
106
+ //this.validEmail = email.includes('@');
107
+ }
108
+
109
+ {{else}}
110
+
111
+ hideError() {return (this.valid || !this.wasFocused || this.isFocused)},
112
+ hideDescription() {return !this.valid && this.wasFocused && !this.isFocused},
113
+ errorMessage: "{{_errorMandatory}}"
114
+ {{/if}}
115
+ };
116
+ }
117
+ </script>
118
+ </div>
@@ -0,0 +1,77 @@
1
+ <div class="relative flex flex-col w-full mb-5" x-data="{ textarea{{nextRandom}}: '{{#if _formField.isValid}}{{{_formField.forHtmlContent}}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}' , valid: false, wasFocused: false, isFocused: false}">
2
+ <div class="w-full h-4 bg-white"></div>
3
+ <textarea
4
+ x-model="textarea{{getRandom}}"
5
+ id="textarea{{getRandom}}"
6
+ @focus="isFocused = true"
7
+ @blur="wasFocused = true; isFocused=false"
8
+ x-on:keyup ="textarea{{getRandom}}.length > 0 ? valid = true : valid = false"
9
+ value=""
10
+ name="{{#if _name}}{{_name}}{{/if}}"
11
+ {{#if _locaKey}}
12
+ title="{{loca _locaKey}}{{#if _required}}*{{/if}}"
13
+ placeholder="{{loca _locaKey}}{{#if _required}}*{{/if}}"
14
+ {{else}}
15
+ {{#if _label}}
16
+ title="{{_label}}{{#if _required}} (Pflichtfeld){{/if}}"
17
+ placeholder="{{_label}}{{#if _required}}*{{/if}}"
18
+ {{/if}}
19
+ {{/if}}
20
+ {{#if _rows}}
21
+ rows="{{_rows}}"
22
+ {{/if}}
23
+ {{#if _cols}}
24
+ cols="{{_cols}}"
25
+ {{/if}}
26
+ {{#if _maxLength}}
27
+ maxlength="{{_maxLength}}"
28
+ {{/if~}}
29
+ {{#if _required}}required{{/if}}
30
+ class="relative w-full px-4 pb-px text-gray-800 placeholder-transparent bg-white border-blue-500 min-h-12 peer border-y focus:border-b-2 focus:pb-0 border-t-transparent focus:outline-none"
31
+ :class="{'border-blue-500': valid || !wasFocused || isFocused,'border-red-500': !valid && wasFocused && !isFocused}"
32
+ >{{#if _formField.isValid}}
33
+ {{{_formField.forHtmlContent}}}
34
+ {{else}}
35
+ {{#if _value}}
36
+ {{_value}}
37
+ {{else}}
38
+ {{_defaultValue}}
39
+ {{/if}}{{/if}}</textarea>
40
+ <label for="textarea{{getRandom}}" class="absolute left-[16px] top-px translate-y-0 translate-x-0 scale-75 text-gray-500
41
+
42
+ peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-x-0 peer-placeholder-shown:translate-y-3
43
+
44
+ peer-focus:translate-x-0 peer-focus:-translate-y-0 peer-focus:scale-75 peer-focus:text-blue-500 origin-top-left transform transition-transform">
45
+ {{#if _locaKey}}
46
+ {{loca _locaKey}}
47
+ {{else}}
48
+ {{#if _label}}
49
+ {{{_label}}}{{#if _required}}*{{/if}}
50
+ {{/if}}
51
+ {{/if}}
52
+ </label>
53
+ {{#if _required}}
54
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
55
+ <div class="hidden w-5 h-5 font-bold" :class="{'hidden': valid || !wasFocused || isFocused }">
56
+ {{> components/base/image/icon _icon="info2" _addClass="w-5 h-5 fill-red-700"}}
57
+ </div>
58
+ </div>
59
+ {{/if}}
60
+ <div class="flex items-end justify-between h-5 font-heading">
61
+ {{#if _description}}
62
+ <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
63
+ {{/if}}
64
+ {{#if _required}}
65
+ <div class="hidden pl-4 text-xs font-bold text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
66
+ {{/if}}
67
+ {{#if _maxLength}}
68
+ <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="textarea{{getRandom}}.length">0</span>/{{_maxLength}}</div>
69
+ {{/if~}}
70
+ </div>
71
+ <div class="hidden">
72
+ <div>DEBUGG</div>
73
+ <div>wasFocused:<span x-text="wasFocused"></span></div>
74
+ <div>valid:<span x-text="valid"></span></div>
75
+ <div>input.length:<span x-text="textarea{{getRandom}}.length "></span></div>
76
+ </div>
77
+ </div>
@@ -18,10 +18,9 @@
18
18
 
19
19
  <div class="c-form__row js-wrapper-{{this.name}}">
20
20
  {{#if this.type.isTextarea}}
21
- {{~> modules/forms/textarea
21
+ {{~> components/forms/textarea
22
22
  _name=this.name
23
23
  _label=this.label
24
- _labelClass="hide"
25
24
  _description=this.description
26
25
  _defaultValue=this.defaultValue
27
26
  _counter=this.counter
@@ -29,10 +28,12 @@
29
28
  _cols=this.columns
30
29
  _required=this.isRequired
31
30
  _maxLength=this.maxLength
31
+ _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
32
32
  }}
33
33
  {{else if this.type.isText}}
34
34
  {{~> components/forms/input_single_line
35
35
  _type=this.type.asString
36
+ _isEmail=this.type.isEmail
36
37
  _name=this.name
37
38
  _label=this.label
38
39
  _labelClass="hide"
@@ -42,7 +43,8 @@
42
43
  _tabindex=(if this.isHidden "-1")
43
44
  _required=this.isRequired
44
45
  _maxLength=this.maxLength
45
- _errorMessage="Bitte füllen Sie diese Pflichtfeld aus"
46
+ _errorMandatory="Bitte füllen Sie dieses Pflichtfeld aus"
47
+ _errorEmail="Bitte geben Sie eine gültige E-Mail-Adresse ein."
46
48
  }}
47
49
  {{else if this.type.isSelect}}
48
50
  {{~> modules/forms/select
@@ -1,10 +1,13 @@
1
- <div class="relative flex flex-col w-full mb-5" x-data="{ input{{nextRandom}}: '' , valid: false, wasFocused: false}">
2
- <input class="relative w-full h-12 px-4 pt-4 text-gray-800 placeholder-transparent bg-white border-blue-500 peer border-y border-t-transparent focus:outline-none"
3
- x-model="input{{getRandom}}"
1
+ <div class="relative flex flex-col w-full mb-5"
2
+ x-data="inputHandler">
3
+ <input class="relative w-full h-12 pt-4 pl-4 text-gray-800 placeholder-transparent bg-white border-blue-500 pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
4
+ :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
5
+ x-model="input{{nextRandom}}"
4
6
  id="input{{getRandom}}"
5
7
  {{#if _required}}
6
- @blur="wasFocused = true;"
7
- x-on:keyup ="input{{getRandom}}.length > 0 ? valid = true : valid = false"
8
+ @focus="isFocused = true"
9
+ @blur="wasFocused = true; isFocused=false"
10
+ x-on:keyup ="input{{getRandom}}.length > 0 ? valid = true : valid = false; validateEmail()"
8
11
  {{/if}}
9
12
  type="{{#if _type}}{{_type}}{{/if}}"
10
13
  name="{{#if _name}}{{_name}}{{/if}}"
@@ -35,12 +38,7 @@
35
38
  {{#if _autoSuggestFeature}}
36
39
  data-hr-search-suggest='{"templateUrl":"{{resourceUrl "suche/index~suggest.jsp"}}"}'{{/if}}
37
40
  >
38
- <div class="hidden">
39
- <div>DEBUGG</div>
40
- <div>wasFocused:<span x-text="wasFocused"></span></div>
41
- <div>valid:<span x-text="valid"></span></div>
42
- <div>input.length:<span x-text="input{{getRandom}}.length "></span></div>
43
- </div>
41
+
44
42
  <label for="input{{getRandom}}" class="absolute left-[16px] top-px translate-y-0 translate-x-0 scale-75 text-gray-500
45
43
 
46
44
  peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-x-0 peer-placeholder-shown:translate-y-3
@@ -58,15 +56,63 @@
58
56
  {{/if}}
59
57
  {{/if}}
60
58
  </label>
59
+ {{#if _required}}
60
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
61
+ <div class="hidden w-5 h-5 font-bold" :class="{'hidden': hideError() }">
62
+ {{> components/base/image/icon _icon="info2" _addClass="w-5 h-5 fill-red-700"}}
63
+ </div>
64
+ </div>
65
+ {{/if}}
61
66
  <div class="flex items-end justify-between h-5 font-heading">
62
67
  {{#if _description}}
63
- <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused}"{{/if}}>{{_description}}</div>
68
+ <div class="pl-4 text-xs text-gray-500" {{#if _required}}:class="{'hidden': hideDescription() }"{{/if}}>{{_description}}</div>
64
69
  {{/if}}
65
70
  {{#if _required}}
66
- <div class="hidden pl-4 text-xs font-bold text-red-700" :class="{'hidden': valid || !wasFocused }" >{{_errorMessage}}</div>
71
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': hideError()}" x-text="errorMessage"></div>
67
72
  {{/if}}
68
73
  {{#if _maxLength}}
69
74
  <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="input{{getRandom}}.length">0</span>/{{_maxLength}}</div>
70
75
  {{/if~}}
71
76
  </div>
72
- </div>
77
+ <div class="hidden">
78
+ <b>DEBUGG</b>
79
+ <div>isFocused:<span x-text="isFocused"></span></div>
80
+ <div>wasFocused:<span x-text="wasFocused"></span></div>
81
+ <div>valid:<span x-text="valid"></span></div>
82
+ <div>validEmail:<span x-text="validEmail"></span></div>
83
+ <div>hideDescription:<span x-text="hideDescription"></span></div>
84
+ <div>hideError:<span x-text="hideError"></span></div>
85
+ <div>input.length:<span x-text="input{{getRandom}}.length "></span></div>
86
+ <div>input:<span x-text="input{{getRandom}} "></span></div>
87
+ <div>errorMessage:<span x-text="errorMessage"></span></div>
88
+ </div>
89
+ <script>
90
+ function inputHandler() {
91
+ return {
92
+ input{{getRandom}}: '{{#if _formField.forHtmlAttribute}}{{_formField.forHtmlAttribute}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}' ,
93
+ valid: false,
94
+ wasFocused: false,
95
+ isFocused: false,
96
+ {{#if _isEmail}}
97
+ validEmail: false,
98
+ errorMessage(){ return !this.valid ? '{{_errorMandatory}}' : '{{_errorEmail}}'},
99
+ hideDescription() {return (!this.valid && this.wasFocused && !this.isFocused) || (!this.validEmail && this.wasFocused && !this.isFocused)},
100
+ hideError() {return !this.hideDescription()},
101
+
102
+ validateEmail() {
103
+ var email = this.input{{getRandom}}
104
+ var emailRegex = /^[a-zA-Z0–9._-]+@[a-zA-Z0–9.-]+\.[a-zA-Z]{2,4}$/;
105
+ this.validEmail = emailRegex.test(email);
106
+ //this.validEmail = email.includes('@');
107
+ }
108
+
109
+ {{else}}
110
+
111
+ hideError() {return (this.valid || !this.wasFocused || this.isFocused)},
112
+ hideDescription() {return !this.valid && this.wasFocused && !this.isFocused},
113
+ errorMessage: "{{_errorMandatory}}"
114
+ {{/if}}
115
+ };
116
+ }
117
+ </script>
118
+ </div>
@@ -0,0 +1,77 @@
1
+ <div class="relative flex flex-col w-full mb-5" x-data="{ textarea{{nextRandom}}: '{{#if _formField.isValid}}{{{_formField.forHtmlContent}}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}' , valid: false, wasFocused: false, isFocused: false}">
2
+ <div class="w-full h-4 bg-white"></div>
3
+ <textarea
4
+ x-model="textarea{{getRandom}}"
5
+ id="textarea{{getRandom}}"
6
+ @focus="isFocused = true"
7
+ @blur="wasFocused = true; isFocused=false"
8
+ x-on:keyup ="textarea{{getRandom}}.length > 0 ? valid = true : valid = false"
9
+ value=""
10
+ name="{{#if _name}}{{_name}}{{/if}}"
11
+ {{#if _locaKey}}
12
+ title="{{loca _locaKey}}{{#if _required}}*{{/if}}"
13
+ placeholder="{{loca _locaKey}}{{#if _required}}*{{/if}}"
14
+ {{else}}
15
+ {{#if _label}}
16
+ title="{{_label}}{{#if _required}} (Pflichtfeld){{/if}}"
17
+ placeholder="{{_label}}{{#if _required}}*{{/if}}"
18
+ {{/if}}
19
+ {{/if}}
20
+ {{#if _rows}}
21
+ rows="{{_rows}}"
22
+ {{/if}}
23
+ {{#if _cols}}
24
+ cols="{{_cols}}"
25
+ {{/if}}
26
+ {{#if _maxLength}}
27
+ maxlength="{{_maxLength}}"
28
+ {{/if~}}
29
+ {{#if _required}}required{{/if}}
30
+ class="relative w-full px-4 pb-px text-gray-800 placeholder-transparent bg-white border-blue-500 min-h-12 peer border-y focus:border-b-2 focus:pb-0 border-t-transparent focus:outline-none"
31
+ :class="{'border-blue-500': valid || !wasFocused || isFocused,'border-red-500': !valid && wasFocused && !isFocused}"
32
+ >{{#if _formField.isValid}}
33
+ {{{_formField.forHtmlContent}}}
34
+ {{else}}
35
+ {{#if _value}}
36
+ {{_value}}
37
+ {{else}}
38
+ {{_defaultValue}}
39
+ {{/if}}{{/if}}</textarea>
40
+ <label for="textarea{{getRandom}}" class="absolute left-[16px] top-px translate-y-0 translate-x-0 scale-75 text-gray-500
41
+
42
+ peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-x-0 peer-placeholder-shown:translate-y-3
43
+
44
+ peer-focus:translate-x-0 peer-focus:-translate-y-0 peer-focus:scale-75 peer-focus:text-blue-500 origin-top-left transform transition-transform">
45
+ {{#if _locaKey}}
46
+ {{loca _locaKey}}
47
+ {{else}}
48
+ {{#if _label}}
49
+ {{{_label}}}{{#if _required}}*{{/if}}
50
+ {{/if}}
51
+ {{/if}}
52
+ </label>
53
+ {{#if _required}}
54
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
55
+ <div class="hidden w-5 h-5 font-bold" :class="{'hidden': valid || !wasFocused || isFocused }">
56
+ {{> components/base/image/icon _icon="info2" _addClass="w-5 h-5 fill-red-700"}}
57
+ </div>
58
+ </div>
59
+ {{/if}}
60
+ <div class="flex items-end justify-between h-5 font-heading">
61
+ {{#if _description}}
62
+ <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
63
+ {{/if}}
64
+ {{#if _required}}
65
+ <div class="hidden pl-4 text-xs font-bold text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
66
+ {{/if}}
67
+ {{#if _maxLength}}
68
+ <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="textarea{{getRandom}}.length">0</span>/{{_maxLength}}</div>
69
+ {{/if~}}
70
+ </div>
71
+ <div class="hidden">
72
+ <div>DEBUGG</div>
73
+ <div>wasFocused:<span x-text="wasFocused"></span></div>
74
+ <div>valid:<span x-text="valid"></span></div>
75
+ <div>input.length:<span x-text="textarea{{getRandom}}.length "></span></div>
76
+ </div>
77
+ </div>
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
8
8
  "repository": "https://github.com/szuelch/hr-design-system-handlebars",
9
- "version": "1.100.2",
9
+ "version": "1.100.4",
10
10
  "scripts": {
11
11
  "test": "echo \"Error: no test specified\" && exit 1",
12
12
  "storybook": "storybook dev -p 6006 public",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  {
16
16
  "@->jsoninclude": "forms/form_fields.inc.json",
17
- "@->contentpath": "input-text-nachname"
17
+ "@->contentpath": "input-text-vorname-required"
18
18
  }
19
19
  ]
20
20
 
@@ -0,0 +1,9 @@
1
+ {
2
+ "fields":[
3
+ {
4
+ "@->jsoninclude": "forms/form_fields.inc.json",
5
+ "@->contentpath": "input-email"
6
+ }
7
+ ]
8
+ }
9
+
@@ -21,13 +21,13 @@
21
21
  },
22
22
  "name":"vorname",
23
23
  "label":"Vorname",
24
- "description":"",
24
+ "description":"Das ist der Beschreibungstext (*Pflichtfeld)",
25
25
  "defaultValue":"",
26
26
  "isHidden":false,
27
27
  "isRequired":true,
28
28
  "maxLength":"20"
29
29
  },
30
- "input-text-nachname":
30
+ "input-text-vorname-prefilled":
31
31
  {
32
32
  "type":{
33
33
  "isText":true,
@@ -36,9 +36,41 @@
36
36
  "name":"nachname",
37
37
  "label":"Nachname",
38
38
  "description":"Das ist der Beschreibungstext von Nachname",
39
+ "defaultValue":"Hier steht schon was",
40
+ "isHidden":false,
41
+ "isRequired":false,
42
+ "maxLength":"140"
43
+ },
44
+ "input-email":
45
+ {
46
+ "type":{
47
+ "isText":true,
48
+ "isEmail":true,
49
+ "asString":"email"
50
+ },
51
+ "name":"email",
52
+ "label":"Email",
53
+ "description":"Das ist der Beschreibungstext von Email",
39
54
  "defaultValue":"",
40
55
  "isHidden":false,
41
56
  "isRequired":true,
42
57
  "maxLength":"140"
43
- }
58
+ },
59
+ "textarea":
60
+ {
61
+ "type":{
62
+ "isTextarea":true,
63
+ "asString":"textarea"
64
+ },
65
+ "name":"textarea",
66
+ "label":"Textarea",
67
+ "description":"Das ist der Beschreibungstext von Textarea",
68
+ "defaultValue":"",
69
+ "isHidden":false,
70
+ "isRequired":true,
71
+ "maxLength":"300",
72
+ "columns":"30",
73
+ "rows":"10",
74
+ "counter":true
75
+ }
44
76
  }
@@ -3,14 +3,6 @@
3
3
  {
4
4
  "@->jsoninclude": "forms/form_fields.inc.json",
5
5
  "@->contentpath": "input-text-vorname"
6
- },
7
- {
8
- "@->jsoninclude": "forms/form_fields.inc.json",
9
- "@->contentpath": "input-text-vorname-required"
10
- },
11
- {
12
- "@->jsoninclude": "forms/form_fields.inc.json",
13
- "@->contentpath": "input-text-nachname"
14
6
  }
15
7
  ]
16
8
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "fields":[
3
+ {
4
+ "@->jsoninclude": "forms/form_fields.inc.json",
5
+ "@->contentpath": "input-text-vorname-required"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "fields":[
3
+ {
4
+ "@->jsoninclude": "forms/form_fields.inc.json",
5
+ "@->contentpath": "input-text-vorname-prefilled"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "fields":[
3
+ {
4
+ "@->jsoninclude": "forms/form_fields.inc.json",
5
+ "@->contentpath": "textarea"
6
+ },{
7
+ "@->jsoninclude": "forms/form_fields.inc.json",
8
+ "@->contentpath": "textarea",
9
+ "@->overrides": [
10
+ {
11
+ "@->contentpath": "isRequired",
12
+ "@->value": false
13
+ }
14
+ ]
15
+ }
16
+ ]
17
+ }
18
+
@@ -1 +1 @@
1
- {"copytextParagraph":[{"isHeadline":true,"text":"Copytext mit Formular"},{"paragraphBoxItem":{"isWebForm":true,"fields":[{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext von Vorname","defaultValue":"","isHidden":false,"isRequired":false},{"type":{"isText":true,"asString":"text"},"name":"nachname","label":"Nachname","description":"Das ist der Beschreibungstext von Nachname","defaultValue":"","isHidden":false,"isRequired":true,"maxLength":"140"}]}}]}
1
+ {"copytextParagraph":[{"isHeadline":true,"text":"Copytext mit Formular"},{"paragraphBoxItem":{"isWebForm":true,"fields":[{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext von Vorname","defaultValue":"","isHidden":false,"isRequired":false},{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext (*Pflichtfeld)","defaultValue":"","isHidden":false,"isRequired":true,"maxLength":"20"}]}}]}
@@ -18,10 +18,9 @@
18
18
 
19
19
  <div class="c-form__row js-wrapper-{{this.name}}">
20
20
  {{#if this.type.isTextarea}}
21
- {{~> modules/forms/textarea
21
+ {{~> components/forms/textarea
22
22
  _name=this.name
23
23
  _label=this.label
24
- _labelClass="hide"
25
24
  _description=this.description
26
25
  _defaultValue=this.defaultValue
27
26
  _counter=this.counter
@@ -29,10 +28,12 @@
29
28
  _cols=this.columns
30
29
  _required=this.isRequired
31
30
  _maxLength=this.maxLength
31
+ _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
32
32
  }}
33
33
  {{else if this.type.isText}}
34
34
  {{~> components/forms/input_single_line
35
35
  _type=this.type.asString
36
+ _isEmail=this.type.isEmail
36
37
  _name=this.name
37
38
  _label=this.label
38
39
  _labelClass="hide"
@@ -42,7 +43,8 @@
42
43
  _tabindex=(if this.isHidden "-1")
43
44
  _required=this.isRequired
44
45
  _maxLength=this.maxLength
45
- _errorMessage="Bitte füllen Sie diese Pflichtfeld aus"
46
+ _errorMandatory="Bitte füllen Sie dieses Pflichtfeld aus"
47
+ _errorEmail="Bitte geben Sie eine gültige E-Mail-Adresse ein."
46
48
  }}
47
49
  {{else if this.type.isSelect}}
48
50
  {{~> modules/forms/select
@@ -0,0 +1 @@
1
+ {"fields":[{"type":{"isText":true,"isEmail":true,"asString":"email"},"name":"email","label":"Email","description":"Das ist der Beschreibungstext von Email","defaultValue":"","isHidden":false,"isRequired":true,"maxLength":"140"}]}
@@ -1 +1 @@
1
- {"fields":[{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext von Vorname","defaultValue":"","isHidden":false,"isRequired":false},{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"","defaultValue":"","isHidden":false,"isRequired":true,"maxLength":"20"},{"type":{"isText":true,"asString":"text"},"name":"nachname","label":"Nachname","description":"Das ist der Beschreibungstext von Nachname","defaultValue":"","isHidden":false,"isRequired":true,"maxLength":"140"}]}
1
+ {"fields":[{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext von Vorname","defaultValue":"","isHidden":false,"isRequired":false}]}
@@ -0,0 +1 @@
1
+ {"fields":[{"type":{"isText":true,"asString":"text"},"name":"vorname","label":"Vorname","description":"Das ist der Beschreibungstext (*Pflichtfeld)","defaultValue":"","isHidden":false,"isRequired":true,"maxLength":"20"}]}
@@ -0,0 +1 @@
1
+ {"fields":[{"type":{"isText":true,"asString":"text"},"name":"nachname","label":"Nachname","description":"Das ist der Beschreibungstext von Nachname","defaultValue":"Hier steht schon was","isHidden":false,"isRequired":false,"maxLength":"140"}]}
@@ -0,0 +1 @@
1
+ {"fields":[{"type":{"isTextarea":true,"asString":"textarea"},"name":"textarea","label":"Textarea","description":"Das ist der Beschreibungstext von Textarea","defaultValue":"","isHidden":false,"isRequired":true,"maxLength":"300","columns":"30","rows":"10","counter":true},{"type":{"isTextarea":true,"asString":"textarea"},"name":"textarea","label":"Textarea","description":"Das ist der Beschreibungstext von Textarea","defaultValue":"","isHidden":false,"isRequired":false,"maxLength":"300","columns":"30","rows":"10","counter":true}]}
@@ -1,10 +1,15 @@
1
1
 
2
2
  import inputJson from './fixtures/form_input.json'
3
+ import inputMandatoryJson from './fixtures/form_input_mandatory.json'
4
+ import inputPrefilledJson from './fixtures/form_input_prefilled.json'
5
+ import textareaJson from './fixtures/form_textarea.json'
6
+ import emailJson from './fixtures/form_email.json'
7
+
3
8
  const handlebars = require('hrHandlebars')
4
9
 
5
10
 
6
11
  export default {
7
- title: 'Komponenten/Formulare/Input',
12
+ title: 'Komponenten/Formulare/Text Felder',
8
13
  decorators: [
9
14
  (Story) => {
10
15
  return `<div class="grid grid-page">
@@ -15,7 +20,17 @@ export default {
15
20
  },
16
21
  ],
17
22
  }
18
- const Template = (args) => {
23
+ const TemplateInput = (args) => {
24
+ let hbsTemplate = handlebars.compile(`
25
+ {{#>components/forms/backgroundBox }}
26
+ <form class="relative flex flex-col justify-center overflow-hidden group" id="form--{{nextRandom}}" action="{{this.url}}" method="post" enctype="{{if this.isMultipart 'multipart/form-data' 'application/x-www-form-urlencoded'}}" accept-charset="utf-8" >
27
+ {{> components/forms/fields }}
28
+ </form>
29
+ {{/components/forms/backgroundBox }}
30
+ `)
31
+ return hbsTemplate({ ...args })
32
+ }
33
+ const TemplateTextarea = (args) => {
19
34
  let hbsTemplate = handlebars.compile(`
20
35
  {{#>components/forms/backgroundBox }}
21
36
  <form class="relative flex flex-col justify-center overflow-hidden group" id="form--{{nextRandom}}" action="{{this.url}}" method="post" enctype="{{if this.isMultipart 'multipart/form-data' 'application/x-www-form-urlencoded'}}" accept-charset="utf-8" >
@@ -26,14 +41,23 @@ const Template = (args) => {
26
41
  return hbsTemplate({ ...args })
27
42
  }
28
43
  export const Input = {
29
- render: Template.bind({}),
30
- name: 'Input - Einzeiliger Text',
44
+ render: TemplateInput.bind({}),
45
+ name: 'Input',
31
46
  args: inputJson,
32
47
  }
33
-
48
+ export const InputMandatory = {
49
+ render: TemplateInput.bind({}),
50
+ name: 'Input:mandatory',
51
+ args: inputMandatoryJson,
52
+ }
53
+ export const InputPrefilled = {
54
+ render: TemplateInput.bind({}),
55
+ name: 'Input:prefilled',
56
+ args: inputPrefilledJson,
57
+ }
34
58
  export const InputFocused = {
35
- render: Template.bind({}),
36
- name: 'Input - Einzeiliger Text Focus',
59
+ render: TemplateInput.bind({}),
60
+ name: 'Input:focus',
37
61
  args: inputJson,
38
62
  parameters: {
39
63
  pseudo: {
@@ -41,4 +65,14 @@ export const InputFocused = {
41
65
 
42
66
  },
43
67
  }
68
+ }
69
+ export const email = {
70
+ render: TemplateInput.bind({}),
71
+ name: 'Email',
72
+ args: emailJson,
73
+ }
74
+ export const Textarea = {
75
+ render: TemplateTextarea.bind({}),
76
+ name: 'Textarea',
77
+ args: textareaJson,
44
78
  }
@@ -1,10 +1,13 @@
1
- <div class="relative flex flex-col w-full mb-5" x-data="{ input{{nextRandom}}: '' , valid: false, wasFocused: false}">
2
- <input class="relative w-full h-12 px-4 pt-4 text-gray-800 placeholder-transparent bg-white border-blue-500 peer border-y border-t-transparent focus:outline-none"
3
- x-model="input{{getRandom}}"
1
+ <div class="relative flex flex-col w-full mb-5"
2
+ x-data="inputHandler">
3
+ <input class="relative w-full h-12 pt-4 pl-4 text-gray-800 placeholder-transparent bg-white border-blue-500 pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
4
+ :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
5
+ x-model="input{{nextRandom}}"
4
6
  id="input{{getRandom}}"
5
7
  {{#if _required}}
6
- @blur="wasFocused = true;"
7
- x-on:keyup ="input{{getRandom}}.length > 0 ? valid = true : valid = false"
8
+ @focus="isFocused = true"
9
+ @blur="wasFocused = true; isFocused=false"
10
+ x-on:keyup ="input{{getRandom}}.length > 0 ? valid = true : valid = false; validateEmail()"
8
11
  {{/if}}
9
12
  type="{{#if _type}}{{_type}}{{/if}}"
10
13
  name="{{#if _name}}{{_name}}{{/if}}"
@@ -35,12 +38,7 @@
35
38
  {{#if _autoSuggestFeature}}
36
39
  data-hr-search-suggest='{"templateUrl":"{{resourceUrl "suche/index~suggest.jsp"}}"}'{{/if}}
37
40
  >
38
- <div class="hidden">
39
- <div>DEBUGG</div>
40
- <div>wasFocused:<span x-text="wasFocused"></span></div>
41
- <div>valid:<span x-text="valid"></span></div>
42
- <div>input.length:<span x-text="input{{getRandom}}.length "></span></div>
43
- </div>
41
+
44
42
  <label for="input{{getRandom}}" class="absolute left-[16px] top-px translate-y-0 translate-x-0 scale-75 text-gray-500
45
43
 
46
44
  peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-x-0 peer-placeholder-shown:translate-y-3
@@ -58,15 +56,63 @@
58
56
  {{/if}}
59
57
  {{/if}}
60
58
  </label>
59
+ {{#if _required}}
60
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
61
+ <div class="hidden w-5 h-5 font-bold" :class="{'hidden': hideError() }">
62
+ {{> components/base/image/icon _icon="info2" _addClass="w-5 h-5 fill-red-700"}}
63
+ </div>
64
+ </div>
65
+ {{/if}}
61
66
  <div class="flex items-end justify-between h-5 font-heading">
62
67
  {{#if _description}}
63
- <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused}"{{/if}}>{{_description}}</div>
68
+ <div class="pl-4 text-xs text-gray-500" {{#if _required}}:class="{'hidden': hideDescription() }"{{/if}}>{{_description}}</div>
64
69
  {{/if}}
65
70
  {{#if _required}}
66
- <div class="hidden pl-4 text-xs font-bold text-red-700" :class="{'hidden': valid || !wasFocused }" >{{_errorMessage}}</div>
71
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': hideError()}" x-text="errorMessage"></div>
67
72
  {{/if}}
68
73
  {{#if _maxLength}}
69
74
  <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="input{{getRandom}}.length">0</span>/{{_maxLength}}</div>
70
75
  {{/if~}}
71
76
  </div>
72
- </div>
77
+ <div class="hidden">
78
+ <b>DEBUGG</b>
79
+ <div>isFocused:<span x-text="isFocused"></span></div>
80
+ <div>wasFocused:<span x-text="wasFocused"></span></div>
81
+ <div>valid:<span x-text="valid"></span></div>
82
+ <div>validEmail:<span x-text="validEmail"></span></div>
83
+ <div>hideDescription:<span x-text="hideDescription"></span></div>
84
+ <div>hideError:<span x-text="hideError"></span></div>
85
+ <div>input.length:<span x-text="input{{getRandom}}.length "></span></div>
86
+ <div>input:<span x-text="input{{getRandom}} "></span></div>
87
+ <div>errorMessage:<span x-text="errorMessage"></span></div>
88
+ </div>
89
+ <script>
90
+ function inputHandler() {
91
+ return {
92
+ input{{getRandom}}: '{{#if _formField.forHtmlAttribute}}{{_formField.forHtmlAttribute}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}' ,
93
+ valid: false,
94
+ wasFocused: false,
95
+ isFocused: false,
96
+ {{#if _isEmail}}
97
+ validEmail: false,
98
+ errorMessage(){ return !this.valid ? '{{_errorMandatory}}' : '{{_errorEmail}}'},
99
+ hideDescription() {return (!this.valid && this.wasFocused && !this.isFocused) || (!this.validEmail && this.wasFocused && !this.isFocused)},
100
+ hideError() {return !this.hideDescription()},
101
+
102
+ validateEmail() {
103
+ var email = this.input{{getRandom}}
104
+ var emailRegex = /^[a-zA-Z0–9._-]+@[a-zA-Z0–9.-]+\.[a-zA-Z]{2,4}$/;
105
+ this.validEmail = emailRegex.test(email);
106
+ //this.validEmail = email.includes('@');
107
+ }
108
+
109
+ {{else}}
110
+
111
+ hideError() {return (this.valid || !this.wasFocused || this.isFocused)},
112
+ hideDescription() {return !this.valid && this.wasFocused && !this.isFocused},
113
+ errorMessage: "{{_errorMandatory}}"
114
+ {{/if}}
115
+ };
116
+ }
117
+ </script>
118
+ </div>
@@ -0,0 +1,77 @@
1
+ <div class="relative flex flex-col w-full mb-5" x-data="{ textarea{{nextRandom}}: '{{#if _formField.isValid}}{{{_formField.forHtmlContent}}}{{else}}{{#if _value}}{{_value}}{{else}}{{_defaultValue}}{{/if}}{{/if}}' , valid: false, wasFocused: false, isFocused: false}">
2
+ <div class="w-full h-4 bg-white"></div>
3
+ <textarea
4
+ x-model="textarea{{getRandom}}"
5
+ id="textarea{{getRandom}}"
6
+ @focus="isFocused = true"
7
+ @blur="wasFocused = true; isFocused=false"
8
+ x-on:keyup ="textarea{{getRandom}}.length > 0 ? valid = true : valid = false"
9
+ value=""
10
+ name="{{#if _name}}{{_name}}{{/if}}"
11
+ {{#if _locaKey}}
12
+ title="{{loca _locaKey}}{{#if _required}}*{{/if}}"
13
+ placeholder="{{loca _locaKey}}{{#if _required}}*{{/if}}"
14
+ {{else}}
15
+ {{#if _label}}
16
+ title="{{_label}}{{#if _required}} (Pflichtfeld){{/if}}"
17
+ placeholder="{{_label}}{{#if _required}}*{{/if}}"
18
+ {{/if}}
19
+ {{/if}}
20
+ {{#if _rows}}
21
+ rows="{{_rows}}"
22
+ {{/if}}
23
+ {{#if _cols}}
24
+ cols="{{_cols}}"
25
+ {{/if}}
26
+ {{#if _maxLength}}
27
+ maxlength="{{_maxLength}}"
28
+ {{/if~}}
29
+ {{#if _required}}required{{/if}}
30
+ class="relative w-full px-4 pb-px text-gray-800 placeholder-transparent bg-white border-blue-500 min-h-12 peer border-y focus:border-b-2 focus:pb-0 border-t-transparent focus:outline-none"
31
+ :class="{'border-blue-500': valid || !wasFocused || isFocused,'border-red-500': !valid && wasFocused && !isFocused}"
32
+ >{{#if _formField.isValid}}
33
+ {{{_formField.forHtmlContent}}}
34
+ {{else}}
35
+ {{#if _value}}
36
+ {{_value}}
37
+ {{else}}
38
+ {{_defaultValue}}
39
+ {{/if}}{{/if}}</textarea>
40
+ <label for="textarea{{getRandom}}" class="absolute left-[16px] top-px translate-y-0 translate-x-0 scale-75 text-gray-500
41
+
42
+ peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-x-0 peer-placeholder-shown:translate-y-3
43
+
44
+ peer-focus:translate-x-0 peer-focus:-translate-y-0 peer-focus:scale-75 peer-focus:text-blue-500 origin-top-left transform transition-transform">
45
+ {{#if _locaKey}}
46
+ {{loca _locaKey}}
47
+ {{else}}
48
+ {{#if _label}}
49
+ {{{_label}}}{{#if _required}}*{{/if}}
50
+ {{/if}}
51
+ {{/if}}
52
+ </label>
53
+ {{#if _required}}
54
+ <div class="absolute top-0 z-10 flex items-center justify-center h-12 right-4">
55
+ <div class="hidden w-5 h-5 font-bold" :class="{'hidden': valid || !wasFocused || isFocused }">
56
+ {{> components/base/image/icon _icon="info2" _addClass="w-5 h-5 fill-red-700"}}
57
+ </div>
58
+ </div>
59
+ {{/if}}
60
+ <div class="flex items-end justify-between h-5 font-heading">
61
+ {{#if _description}}
62
+ <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
63
+ {{/if}}
64
+ {{#if _required}}
65
+ <div class="hidden pl-4 text-xs font-bold text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
66
+ {{/if}}
67
+ {{#if _maxLength}}
68
+ <div class="px-4 ml-auto text-xs text-gray-500"><span x-text="textarea{{getRandom}}.length">0</span>/{{_maxLength}}</div>
69
+ {{/if~}}
70
+ </div>
71
+ <div class="hidden">
72
+ <div>DEBUGG</div>
73
+ <div>wasFocused:<span x-text="wasFocused"></span></div>
74
+ <div>valid:<span x-text="valid"></span></div>
75
+ <div>input.length:<span x-text="textarea{{getRandom}}.length "></span></div>
76
+ </div>
77
+ </div>
@@ -167,6 +167,9 @@ module.exports = {
167
167
  maxHeight: {
168
168
  stage: '34.3125rem',
169
169
  },
170
+ minHeight: {
171
+ 12: '3rem',
172
+ },
170
173
  maxWidth: {
171
174
  '1/4': '25%',
172
175
  '1/3': '33.33333333%',