hr-design-system-handlebars 1.101.3 → 1.102.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # v1.102.0 (Tue Sep 24 2024)
2
+
3
+ #### 🚀 Enhancement
4
+
5
+ - DPE-3290 ✨ select field for form [#1074](https://github.com/mumprod/hr-design-system-handlebars/pull/1074) ([@vascoeduardo](https://github.com/vascoeduardo))
6
+
7
+ #### Authors: 1
8
+
9
+ - Vasco ([@vascoeduardo](https://github.com/vascoeduardo))
10
+
11
+ ---
12
+
1
13
  # v1.101.3 (Tue Sep 24 2024)
2
14
 
3
15
  #### ⚠️ Pushed to `main`
@@ -426,7 +426,7 @@ video {
426
426
  font-stretch: condensed;
427
427
  }
428
428
 
429
- .-translate-x-1\/2, .-translate-x-2\/4, .-translate-y-1\/2, .translate-x-0, .translate-y-0, .translate-y-12, .translate-y-3, .translate-y-8, .-rotate-45, .rotate-180, .rotate-45, .scale-100, .scale-50, .scale-75, .scale-y-100, .scale-y-90, .transform, .is-loading::after, label, .hover\:scale-105, .active\:scale-95, .peer-placeholder-shown\:translate-x-0, .peer-placeholder-shown\:translate-y-3, .peer-placeholder-shown\:scale-100, .peer-focus\:translate-x-0, .peer-focus\:translate-y-0, .peer-focus\:scale-75 {
429
+ .-translate-x-1\/2, .-translate-x-2\/4, .-translate-y-1\/2, .translate-x-0, .translate-y-0, .translate-y-12, .translate-y-3, .translate-y-8, .-rotate-45, .rotate-180, .rotate-45, .scale-100, .scale-50, .scale-75, .scale-y-100, .scale-y-90, .transform, .is-loading::after, label, .hover\:scale-105, .active\:scale-95, .peer-placeholder-shown\:translate-x-0, .peer-placeholder-shown\:translate-y-3, .peer-placeholder-shown\:scale-100, .peer-focus\:translate-x-0, .peer-focus\:translate-y-0, .peer-focus\:rotate-180, .peer-focus\:scale-75 {
430
430
  --tw-translate-x: 0;
431
431
  --tw-translate-y: 0;
432
432
  --tw-rotate: 0;
@@ -1136,9 +1136,6 @@ article.indexTextDS .indexTextHighlighted .link {
1136
1136
  .right-0 {
1137
1137
  right: 0px;
1138
1138
  }
1139
- .right-3 {
1140
- right: 0.75rem;
1141
- }
1142
1139
  .right-4 {
1143
1140
  right: 1rem;
1144
1141
  }
@@ -1160,6 +1157,12 @@ article.indexTextDS .indexTextHighlighted .link {
1160
1157
  .top-0\.5 {
1161
1158
  top: 0.125rem;
1162
1159
  }
1160
+ .top-1 {
1161
+ top: 0.25rem;
1162
+ }
1163
+ .top-1\.5 {
1164
+ top: 0.375rem;
1165
+ }
1163
1166
  .top-1\/2 {
1164
1167
  top: 50%;
1165
1168
  }
@@ -2464,6 +2467,10 @@ article.indexTextDS .indexTextHighlighted .link {
2464
2467
  --tw-bg-opacity: 1;
2465
2468
  background-color: rgba(243, 244, 246, var(--tw-bg-opacity));
2466
2469
  }
2470
+ .bg-gray-400 {
2471
+ --tw-bg-opacity: 1;
2472
+ background-color: rgba(156, 163, 175, var(--tw-bg-opacity));
2473
+ }
2467
2474
  .bg-gray-500 {
2468
2475
  --tw-bg-opacity: 1;
2469
2476
  background-color: rgba(107, 114, 128, var(--tw-bg-opacity));
@@ -2653,6 +2660,9 @@ article.indexTextDS .indexTextHighlighted .link {
2653
2660
  .fill-\[\#606060\] {
2654
2661
  fill: #606060;
2655
2662
  }
2663
+ .fill-blue-500 {
2664
+ fill: #3b82f6;
2665
+ }
2656
2666
  .fill-blue-congress-hex {
2657
2667
  fill: #005293;
2658
2668
  }
@@ -3466,7 +3476,7 @@ article.indexTextDS .indexTextHighlighted .link {
3466
3476
  border-bottom-color: var(--color-secondary-ds);
3467
3477
  }
3468
3478
  .counter-reset {
3469
- counter-reset: cnt1727163839066;
3479
+ counter-reset: cnt1727170647026;
3470
3480
  }
3471
3481
  .hyphens-auto {
3472
3482
  -webkit-hyphens: auto;
@@ -3874,7 +3884,7 @@ article.indexTextDS .indexTextHighlighted .link {
3874
3884
  --tw-ring-color: rgba(255, 255, 255, 0.5);
3875
3885
  }
3876
3886
  .-ordered {
3877
- counter-increment: cnt1727163839066 1;
3887
+ counter-increment: cnt1727170647026 1;
3878
3888
  }
3879
3889
  .-ordered::before {
3880
3890
  position: absolute;
@@ -3890,7 +3900,7 @@ article.indexTextDS .indexTextHighlighted .link {
3890
3900
  letter-spacing: .0125em;
3891
3901
  --tw-text-opacity: 1;
3892
3902
  color: rgba(0, 0, 0, var(--tw-text-opacity));
3893
- content: counter(cnt1727163839066);
3903
+ content: counter(cnt1727170647026);
3894
3904
  }
3895
3905
  /*! ****************************/
3896
3906
  /*! DataPolicy stuff */
@@ -4007,6 +4017,12 @@ select:has(option:checked:not([value=""])) + label {
4007
4017
  --tw-scale-y: .75;
4008
4018
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
4009
4019
  }
4020
+ select[\:has\(option\:checked\[value\%3D\%22\%22\]\)] {
4021
+ color: transparent;
4022
+ }
4023
+ select:has(option:checked[value=""]) {
4024
+ color: transparent;
4025
+ }
4010
4026
  .\[-T\:\+Z\] {
4011
4027
  --t: +Z;
4012
4028
  }
@@ -5984,11 +6000,21 @@ select:has(option:checked:not([value=""])) + label {
5984
6000
  --tw-translate-y: 0px;
5985
6001
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
5986
6002
  }
6003
+ .peer:focus ~ .peer-focus\:rotate-180 {
6004
+ --tw-rotate: 180deg;
6005
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
6006
+ }
5987
6007
  .peer:focus ~ .peer-focus\:scale-75 {
5988
6008
  --tw-scale-x: .75;
5989
6009
  --tw-scale-y: .75;
5990
6010
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
5991
6011
  }
6012
+ .peer:focus ~ .peer-focus\:border-l-0 {
6013
+ border-left-width: 0px;
6014
+ }
6015
+ .peer:focus ~ .peer-focus\:border-r {
6016
+ border-right-width: 1px;
6017
+ }
5992
6018
  .peer:focus ~ .peer-focus\:text-blue-500 {
5993
6019
  --tw-text-opacity: 1;
5994
6020
  color: rgba(59, 130, 246, var(--tw-text-opacity));
@@ -20,6 +20,7 @@ AsyncAlpine.init(Alpine)
20
20
 
21
21
  .data('socialSharingHandler', ()=> import('components/social_sharing/socialSharingHandler.alpine.js'))
22
22
  .data('inputHandler', ()=> import('components/forms/inputHandler.alpine.js'))
23
+ .data('selectHandler', ()=> import('components/forms/selectHandler.alpine.js'))
23
24
  .start()
24
25
 
25
26
  window.Alpine = Alpine
@@ -0,0 +1,15 @@
1
+ export default function selectHandler(element) {
2
+ return {
3
+ [element]: '',
4
+ valid: false,
5
+ wasFocused: false,
6
+ isFocused: false,
7
+ validEmail: false,
8
+ hideDescription() {
9
+ return Boolean(!this.valid && this.wasFocused && !this.isFocused)
10
+ },
11
+ hideError() {
12
+ return Boolean(!this.hideDescription())
13
+ }
14
+ };
15
+ }
@@ -54,6 +54,7 @@
54
54
  _description=this.description
55
55
  _items=this.options
56
56
  _required=this.isRequired
57
+ _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
57
58
  }}
58
59
  {{else if this.type.isChoice}}
59
60
  {{#if this.isGrouped }}
@@ -1,30 +1,70 @@
1
- <div class="relative flex flex-col w-full mb-5 " ax-load=""
2
- x-data="inputHandler('select9339','Bitte wählen Sie eine Option aus', false, '')">
1
+ <div class="relative flex flex-col w-full mb-5 "
2
+ ax-load
3
+ x-data="selectHandler('select{{nextRandom}}')"
4
+ x-ignore
5
+ >
3
6
  <select
4
- class="relative w-full h-12 pt-4 pl-4 text-gray-800 border-blue-500 appearance-none bg- pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
5
- :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }" x-model="select9339"
6
- id="select9339" name="options" title="Wählen Sie eine Option" aria-label="Wählen Sie eine Option" >
7
- <option value="" selected></option>
8
- <option value="1">Option 1</option>
9
- <option value="2">Option 2</option>
10
- <option value="3">Option 3</option>
7
+ class="relative w-full h-12 pt-4 pl-4 text-gray-800 bg-white border-blue-500 appearance-none bg- pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
8
+ :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
9
+ x-model="select{{getRandom}}"
10
+ id="select{{getRandom}}"
11
+ title="{{#if _locaKey}}{{loca _locaKey}}{{else}}{{#if _Label}}{{_label}}{{#if _required}}*{{/if}}{{/if}}{{/if}}"
12
+ name="{{#if _name}}{{_name}}{{/if}}"
13
+ {{#if _required}}required{{/if}}
14
+ {{#if _required}}
15
+ @focus="isFocused = true;"
16
+ @blur="wasFocused = true; isFocused=false"
17
+ x-on:change ="select{{getRandom}}.value != '' ? valid = true : valid = false;"
18
+ {{/if}}
19
+ >
20
+ <option class="text-white bg-gray-400" value=""{{#if _required}} disabled{{/if}} selected>
21
+ {{#if _locaKey}}
22
+ {{loca _locaKey}}{{#if _required}}*{{/if}}
23
+ {{else}}
24
+ {{#if _label}}
25
+ {{_label}}{{#if _required}}*{{/if}}
26
+ {{/if}}
27
+ {{/if}}
28
+ </option>
29
+ {{#if _options}}
30
+ {{~#each _options~}}
31
+ <option class="text-black" value="{{this.id}}" {{#if this.isSelected}}selected{{/if}}>{{this.name}}</option>
32
+ {{~/each~}}
33
+ {{else}}
34
+ {{#each _items}}
35
+ <option class="text-black" value="{{this.value}}" {{#if this.selected}}selected{{/if}}>{{this.label}}</option>
36
+ {{/each}}
37
+ {{/if}}
11
38
  </select>
12
- <label for="select9339"
39
+ <label for="select{{getRandom}}"
13
40
  class="absolute pointer-events-none left-[16px] top-0 translate-y-3 translate-x-0 scale-100 text-gray-500
14
-
15
41
  peer-focus:text-blue-500 peer-focus:scale-75 peer-focus:translate-y-0 peer-focus:top-px
16
-
17
-
18
-
19
42
  origin-top-left transform transition-transform
20
- ">
21
-
22
- Wen möchten Sie erreichen?*
43
+ ">
44
+ {{_label}}{{#if _required}}*{{/if}}
23
45
  </label>
24
- <!-- Optional custom dropdown arrow icon -->
25
- <div class="absolute transform -translate-y-1/2 pointer-events-none right-3 top-1/2">
26
- <svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
27
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
28
- </svg>
46
+ <div class="flex items-end justify-between h-5 font-heading">
47
+ {{#if _description}}
48
+ <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
49
+ {{/if}}
50
+ {{#if _required}}
51
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
52
+ {{/if}}
29
53
  </div>
54
+ <div class="absolute right-0 p-4 py-3 transform border-l peer-focus:border-r peer-focus:border-l-0 pointer-events-none top-1.5 peer-focus:rotate-180">
55
+ {{> components/base/image/icon _icon="arrow-down" _addClass="w-3 h-3 fill-blue-500 dark:fill-text-dark "}}
56
+ </div>
57
+ <div class="hidden">
58
+ <div class="px-4 py-2 font-bold text-white bg-red-500 rounded-t">
59
+ DEBUG
60
+ </div>
61
+ <div class="px-4 py-3 text-red-700 bg-red-100 border border-t-0 border-red-400 rounded-b">
62
+ <div>isFocused:<span x-text="isFocused" class="font-bold" :class="isFocused ? 'text-green-800' : 'text-red-700'"></span></div>
63
+ <div>wasFocused:<span x-text="wasFocused" class="font-bold" :class="wasFocused ? 'text-green-800' : 'text-red-700'"></span></div>
64
+ <div>valid:<span x-text="valid" class="font-bold" :class="valid ? 'text-green-800' : 'text-red-700'"></span></div>
65
+ <div>hideDescription:<span x-text="hideDescription()" class="font-bold" :class="hideDescription() ? 'text-green-800' : 'text-red-700'"></span></div>
66
+ <div>hideError:<span x-text="hideError()" class="font-bold" :class="hideError() ? 'text-green-800' : 'text-red-700'"></span></div>
67
+ <div>select:<span x-text="select{{getRandom}}" class="font-bold" ></span></div>
68
+ </div>
69
+ </div>
30
70
  </div>
@@ -54,6 +54,7 @@
54
54
  _description=this.description
55
55
  _items=this.options
56
56
  _required=this.isRequired
57
+ _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
57
58
  }}
58
59
  {{else if this.type.isChoice}}
59
60
  {{#if this.isGrouped }}
@@ -1,30 +1,70 @@
1
- <div class="relative flex flex-col w-full mb-5 " ax-load=""
2
- x-data="inputHandler('select9339','Bitte wählen Sie eine Option aus', false, '')">
1
+ <div class="relative flex flex-col w-full mb-5 "
2
+ ax-load
3
+ x-data="selectHandler('select{{nextRandom}}')"
4
+ x-ignore
5
+ >
3
6
  <select
4
- class="relative w-full h-12 pt-4 pl-4 text-gray-800 border-blue-500 appearance-none bg- pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
5
- :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }" x-model="select9339"
6
- id="select9339" name="options" title="Wählen Sie eine Option" aria-label="Wählen Sie eine Option" >
7
- <option value="" selected></option>
8
- <option value="1">Option 1</option>
9
- <option value="2">Option 2</option>
10
- <option value="3">Option 3</option>
7
+ class="relative w-full h-12 pt-4 pl-4 text-gray-800 bg-white border-blue-500 appearance-none bg- pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
8
+ :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
9
+ x-model="select{{getRandom}}"
10
+ id="select{{getRandom}}"
11
+ title="{{#if _locaKey}}{{loca _locaKey}}{{else}}{{#if _Label}}{{_label}}{{#if _required}}*{{/if}}{{/if}}{{/if}}"
12
+ name="{{#if _name}}{{_name}}{{/if}}"
13
+ {{#if _required}}required{{/if}}
14
+ {{#if _required}}
15
+ @focus="isFocused = true;"
16
+ @blur="wasFocused = true; isFocused=false"
17
+ x-on:change ="select{{getRandom}}.value != '' ? valid = true : valid = false;"
18
+ {{/if}}
19
+ >
20
+ <option class="text-white bg-gray-400" value=""{{#if _required}} disabled{{/if}} selected>
21
+ {{#if _locaKey}}
22
+ {{loca _locaKey}}{{#if _required}}*{{/if}}
23
+ {{else}}
24
+ {{#if _label}}
25
+ {{_label}}{{#if _required}}*{{/if}}
26
+ {{/if}}
27
+ {{/if}}
28
+ </option>
29
+ {{#if _options}}
30
+ {{~#each _options~}}
31
+ <option class="text-black" value="{{this.id}}" {{#if this.isSelected}}selected{{/if}}>{{this.name}}</option>
32
+ {{~/each~}}
33
+ {{else}}
34
+ {{#each _items}}
35
+ <option class="text-black" value="{{this.value}}" {{#if this.selected}}selected{{/if}}>{{this.label}}</option>
36
+ {{/each}}
37
+ {{/if}}
11
38
  </select>
12
- <label for="select9339"
39
+ <label for="select{{getRandom}}"
13
40
  class="absolute pointer-events-none left-[16px] top-0 translate-y-3 translate-x-0 scale-100 text-gray-500
14
-
15
41
  peer-focus:text-blue-500 peer-focus:scale-75 peer-focus:translate-y-0 peer-focus:top-px
16
-
17
-
18
-
19
42
  origin-top-left transform transition-transform
20
- ">
21
-
22
- Wen möchten Sie erreichen?*
43
+ ">
44
+ {{_label}}{{#if _required}}*{{/if}}
23
45
  </label>
24
- <!-- Optional custom dropdown arrow icon -->
25
- <div class="absolute transform -translate-y-1/2 pointer-events-none right-3 top-1/2">
26
- <svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
27
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
28
- </svg>
46
+ <div class="flex items-end justify-between h-5 font-heading">
47
+ {{#if _description}}
48
+ <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
49
+ {{/if}}
50
+ {{#if _required}}
51
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
52
+ {{/if}}
29
53
  </div>
54
+ <div class="absolute right-0 p-4 py-3 transform border-l peer-focus:border-r peer-focus:border-l-0 pointer-events-none top-1.5 peer-focus:rotate-180">
55
+ {{> components/base/image/icon _icon="arrow-down" _addClass="w-3 h-3 fill-blue-500 dark:fill-text-dark "}}
56
+ </div>
57
+ <div class="hidden">
58
+ <div class="px-4 py-2 font-bold text-white bg-red-500 rounded-t">
59
+ DEBUG
60
+ </div>
61
+ <div class="px-4 py-3 text-red-700 bg-red-100 border border-t-0 border-red-400 rounded-b">
62
+ <div>isFocused:<span x-text="isFocused" class="font-bold" :class="isFocused ? 'text-green-800' : 'text-red-700'"></span></div>
63
+ <div>wasFocused:<span x-text="wasFocused" class="font-bold" :class="wasFocused ? 'text-green-800' : 'text-red-700'"></span></div>
64
+ <div>valid:<span x-text="valid" class="font-bold" :class="valid ? 'text-green-800' : 'text-red-700'"></span></div>
65
+ <div>hideDescription:<span x-text="hideDescription()" class="font-bold" :class="hideDescription() ? 'text-green-800' : 'text-red-700'"></span></div>
66
+ <div>hideError:<span x-text="hideError()" class="font-bold" :class="hideError() ? 'text-green-800' : 'text-red-700'"></span></div>
67
+ <div>select:<span x-text="select{{getRandom}}" class="font-bold" ></span></div>
68
+ </div>
69
+ </div>
30
70
  </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.101.3",
9
+ "version": "1.102.0",
10
10
  "scripts": {
11
11
  "test": "echo \"Error: no test specified\" && exit 1",
12
12
  "storybook": "storybook dev -p 6006 public",
@@ -454,4 +454,9 @@
454
454
  @apply top-px scale-75 translate-y-0
455
455
  }
456
456
 
457
+ select:has(option:checked[value=""]) {
458
+ @apply text-transparent
459
+ }
460
+
461
+
457
462
  }
@@ -1,104 +1,121 @@
1
1
  {
2
- "input-text-vorname":
3
- {
4
- "type":{
5
- "isText":true,
6
- "asString":"text"
2
+ "input-text-vorname": {
3
+ "type": {
4
+ "isText": true,
5
+ "asString": "text"
7
6
  },
8
- "name":"vorname",
9
- "label":"Vorname",
10
- "description":"Das ist der Beschreibungstext von Vorname",
11
- "defaultValue":"",
12
- "isHidden":false,
13
- "isRequired":false
14
-
7
+ "name": "vorname",
8
+ "label": "Vorname",
9
+ "description": "Das ist der Beschreibungstext von Vorname",
10
+ "defaultValue": "",
11
+ "isHidden": false,
12
+ "isRequired": false
15
13
  },
16
- "input-text-vorname-required":
17
- {
18
- "type":{
19
- "isText":true,
20
- "asString":"text"
14
+ "input-text-vorname-required": {
15
+ "type": {
16
+ "isText": true,
17
+ "asString": "text"
21
18
  },
22
- "name":"vorname",
23
- "label":"Vorname",
24
- "description":"Das ist der Beschreibungstext (*Pflichtfeld)",
25
- "defaultValue":"",
26
- "isHidden":false,
27
- "isRequired":true,
28
- "maxLength":"140"
19
+ "name": "vorname",
20
+ "label": "Vorname",
21
+ "description": "Das ist der Beschreibungstext (*Pflichtfeld)",
22
+ "defaultValue": "",
23
+ "isHidden": false,
24
+ "isRequired": true,
25
+ "maxLength": "140"
29
26
  },
30
- "input-text-nachname-required":
31
- {
32
- "type":{
33
- "isText":true,
34
- "asString":"text"
27
+ "input-text-nachname-required": {
28
+ "type": {
29
+ "isText": true,
30
+ "asString": "text"
35
31
  },
36
- "name":"nachname",
37
- "label":"Nachname",
38
- "description":"",
39
- "defaultValue":"",
40
- "isHidden":false,
41
- "isRequired":true,
42
- "maxLength":"140"
32
+ "name": "nachname",
33
+ "label": "Nachname",
34
+ "description": "",
35
+ "defaultValue": "",
36
+ "isHidden": false,
37
+ "isRequired": true,
38
+ "maxLength": "140"
43
39
  },
44
- "input-text-vorname-prefilled":
45
- {
46
- "type":{
47
- "isText":true,
48
- "asString":"text"
40
+ "input-text-vorname-prefilled": {
41
+ "type": {
42
+ "isText": true,
43
+ "asString": "text"
49
44
  },
50
- "name":"nachname",
51
- "label":"Nachname",
52
- "description":"Das ist der Beschreibungstext von Nachname",
53
- "defaultValue":"Hier steht schon was",
54
- "isHidden":false,
55
- "isRequired":false,
56
- "maxLength":"140"
45
+ "name": "nachname",
46
+ "label": "Nachname",
47
+ "description": "Das ist der Beschreibungstext von Nachname",
48
+ "defaultValue": "Hier steht schon was",
49
+ "isHidden": false,
50
+ "isRequired": false,
51
+ "maxLength": "140"
57
52
  },
58
- "input-email":
59
- {
60
- "type":{
61
- "isText":true,
62
- "isEmail":true,
63
- "asString":"email"
53
+ "input-email": {
54
+ "type": {
55
+ "isText": true,
56
+ "isEmail": true,
57
+ "asString": "email"
64
58
  },
65
- "name":"email",
66
- "label":"Email",
67
- "description":"Das ist der Beschreibungstext von Email",
68
- "defaultValue":"",
69
- "isHidden":false,
70
- "isRequired":true,
71
- "maxLength":"140"
59
+ "name": "email",
60
+ "label": "Email",
61
+ "description": "Das ist der Beschreibungstext von Email",
62
+ "defaultValue": "",
63
+ "isHidden": false,
64
+ "isRequired": true,
65
+ "maxLength": "140"
72
66
  },
73
- "textarea":
74
- {
75
- "type":{
76
- "isTextarea":true,
77
- "asString":"textarea"
67
+ "textarea": {
68
+ "type": {
69
+ "isTextarea": true,
70
+ "asString": "textarea"
78
71
  },
79
- "name":"textarea",
80
- "label":"Textarea",
81
- "description":"Das ist der Beschreibungstext von Textarea",
82
- "defaultValue":"",
83
- "isHidden":false,
84
- "isRequired":true,
85
- "maxLength":"300",
86
- "columns":"30",
87
- "rows":"10",
88
- "counter":true
72
+ "name": "textarea",
73
+ "label": "Textarea",
74
+ "description": "Das ist der Beschreibungstext von Textarea",
75
+ "defaultValue": "",
76
+ "isHidden": false,
77
+ "isRequired": true,
78
+ "maxLength": "300",
79
+ "columns": "30",
80
+ "rows": "10",
81
+ "counter": true
89
82
  },
90
- "select":
91
- {
92
- "type":{
93
- "isSelect":true,
94
- "asString":"select"
83
+ "select": {
84
+ "type": {
85
+ "isSelect": true,
86
+ "asString": "select"
95
87
  },
96
- "name":"Select Name",
97
- "label":"Select Label",
98
- "description":"Das ist der Beschreibungstext von Select",
99
- "defaultValue":"",
100
- "isHidden":false,
101
- "isRequired":false
102
-
103
- }
104
- }
88
+ "name": "Select Name",
89
+ "label": "Wen möchten Sie erreichen?",
90
+ "description": "Das ist der Beschreibungstext von Select",
91
+ "defaultValue": "",
92
+ "isHidden": false,
93
+ "isRequired": true,
94
+ "options": [
95
+ {
96
+ "id": "option1",
97
+ "value": "option1",
98
+ "selected": false,
99
+ "label": "Option 1"
100
+ },
101
+ {
102
+ "id": "option2",
103
+ "value": "option2",
104
+ "selected": false,
105
+ "label": "Option 2"
106
+ },
107
+ {
108
+ "id": "option3",
109
+ "value": "option3",
110
+ "selected": false,
111
+ "label": "Option 3"
112
+ },
113
+ {
114
+ "id": "option4",
115
+ "value": "option4",
116
+ "selected": false,
117
+ "label": "Option 4"
118
+ }
119
+ ]
120
+ }
121
+ }
@@ -1,8 +1,18 @@
1
1
  {
2
- "fields":[
3
- {
4
- "@->jsoninclude": "forms/form_fields.inc.json",
5
- "@->contentpath": "select"
6
- }
2
+ "fields": [
3
+ {
4
+ "@->jsoninclude": "forms/form_fields.inc.json",
5
+ "@->contentpath": "select"
6
+ },
7
+ {
8
+ "@->jsoninclude": "forms/form_fields.inc.json",
9
+ "@->contentpath": "select",
10
+ "@->overrides": [
11
+ {
12
+ "@->contentpath": "isRequired",
13
+ "@->value": false
14
+ }
7
15
  ]
16
+ }
17
+ ]
8
18
  }
@@ -20,6 +20,7 @@ AsyncAlpine.init(Alpine)
20
20
 
21
21
  .data('socialSharingHandler', ()=> import('components/social_sharing/socialSharingHandler.alpine.js'))
22
22
  .data('inputHandler', ()=> import('components/forms/inputHandler.alpine.js'))
23
+ .data('selectHandler', ()=> import('components/forms/selectHandler.alpine.js'))
23
24
  .start()
24
25
 
25
26
  window.Alpine = Alpine
@@ -54,6 +54,7 @@
54
54
  _description=this.description
55
55
  _items=this.options
56
56
  _required=this.isRequired
57
+ _errorMessage="Bitte füllen Sie dieses Pflichtfeld aus"
57
58
  }}
58
59
  {{else if this.type.isChoice}}
59
60
  {{#if this.isGrouped }}
@@ -1 +1 @@
1
- {"fields":[{"type":{"isSelect":true,"asString":"select"},"name":"Select Name","label":"Select Label","description":"Das ist der Beschreibungstext von Select","defaultValue":"","isHidden":false,"isRequired":false}]}
1
+ {"fields":[{"type":{"isSelect":true,"asString":"select"},"name":"Select Name","label":"Wen möchten Sie erreichen?","description":"Das ist der Beschreibungstext von Select","defaultValue":"","isHidden":false,"isRequired":true,"options":[{"id":"option1","value":"option1","selected":false,"label":"Option 1"},{"id":"option2","value":"option2","selected":false,"label":"Option 2"},{"id":"option3","value":"option3","selected":false,"label":"Option 3"},{"id":"option4","value":"option4","selected":false,"label":"Option 4"}]},{"type":{"isSelect":true,"asString":"select"},"name":"Select Name","label":"Wen möchten Sie erreichen?","description":"Das ist der Beschreibungstext von Select","defaultValue":"","isHidden":false,"isRequired":false,"options":[{"id":"option1","value":"option1","selected":false,"label":"Option 1"},{"id":"option2","value":"option2","selected":false,"label":"Option 2"},{"id":"option3","value":"option3","selected":false,"label":"Option 3"},{"id":"option4","value":"option4","selected":false,"label":"Option 4"}]}]}
@@ -1,30 +1,70 @@
1
- <div class="relative flex flex-col w-full mb-5 " ax-load=""
2
- x-data="inputHandler('select9339','Bitte wählen Sie eine Option aus', false, '')">
1
+ <div class="relative flex flex-col w-full mb-5 "
2
+ ax-load
3
+ x-data="selectHandler('select{{nextRandom}}')"
4
+ x-ignore
5
+ >
3
6
  <select
4
- class="relative w-full h-12 pt-4 pl-4 text-gray-800 border-blue-500 appearance-none bg- pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
5
- :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }" x-model="select9339"
6
- id="select9339" name="options" title="Wählen Sie eine Option" aria-label="Wählen Sie eine Option" >
7
- <option value="" selected></option>
8
- <option value="1">Option 1</option>
9
- <option value="2">Option 2</option>
10
- <option value="3">Option 3</option>
7
+ class="relative w-full h-12 pt-4 pl-4 text-gray-800 bg-white border-blue-500 appearance-none bg- pr-9 peer border-y focus:border-y-2 border-t-transparent focus:outline-none"
8
+ :class="{'border-blue-500': hideError(),'border-red-700': hideDescription() }"
9
+ x-model="select{{getRandom}}"
10
+ id="select{{getRandom}}"
11
+ title="{{#if _locaKey}}{{loca _locaKey}}{{else}}{{#if _Label}}{{_label}}{{#if _required}}*{{/if}}{{/if}}{{/if}}"
12
+ name="{{#if _name}}{{_name}}{{/if}}"
13
+ {{#if _required}}required{{/if}}
14
+ {{#if _required}}
15
+ @focus="isFocused = true;"
16
+ @blur="wasFocused = true; isFocused=false"
17
+ x-on:change ="select{{getRandom}}.value != '' ? valid = true : valid = false;"
18
+ {{/if}}
19
+ >
20
+ <option class="text-white bg-gray-400" value=""{{#if _required}} disabled{{/if}} selected>
21
+ {{#if _locaKey}}
22
+ {{loca _locaKey}}{{#if _required}}*{{/if}}
23
+ {{else}}
24
+ {{#if _label}}
25
+ {{_label}}{{#if _required}}*{{/if}}
26
+ {{/if}}
27
+ {{/if}}
28
+ </option>
29
+ {{#if _options}}
30
+ {{~#each _options~}}
31
+ <option class="text-black" value="{{this.id}}" {{#if this.isSelected}}selected{{/if}}>{{this.name}}</option>
32
+ {{~/each~}}
33
+ {{else}}
34
+ {{#each _items}}
35
+ <option class="text-black" value="{{this.value}}" {{#if this.selected}}selected{{/if}}>{{this.label}}</option>
36
+ {{/each}}
37
+ {{/if}}
11
38
  </select>
12
- <label for="select9339"
39
+ <label for="select{{getRandom}}"
13
40
  class="absolute pointer-events-none left-[16px] top-0 translate-y-3 translate-x-0 scale-100 text-gray-500
14
-
15
41
  peer-focus:text-blue-500 peer-focus:scale-75 peer-focus:translate-y-0 peer-focus:top-px
16
-
17
-
18
-
19
42
  origin-top-left transform transition-transform
20
- ">
21
-
22
- Wen möchten Sie erreichen?*
43
+ ">
44
+ {{_label}}{{#if _required}}*{{/if}}
23
45
  </label>
24
- <!-- Optional custom dropdown arrow icon -->
25
- <div class="absolute transform -translate-y-1/2 pointer-events-none right-3 top-1/2">
26
- <svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
27
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
28
- </svg>
46
+ <div class="flex items-end justify-between h-5 font-heading">
47
+ {{#if _description}}
48
+ <div class="pl-4 text-xs text-gray-500 min-h- " {{#if _required}}:class="{'hidden': !valid && wasFocused && !isFocused}"{{/if}}>{{_description}}</div>
49
+ {{/if}}
50
+ {{#if _required}}
51
+ <div class="hidden pl-4 text-xs text-red-700" :class="{'hidden': valid || !wasFocused || isFocused}" >{{_errorMessage}}</div>
52
+ {{/if}}
29
53
  </div>
54
+ <div class="absolute right-0 p-4 py-3 transform border-l peer-focus:border-r peer-focus:border-l-0 pointer-events-none top-1.5 peer-focus:rotate-180">
55
+ {{> components/base/image/icon _icon="arrow-down" _addClass="w-3 h-3 fill-blue-500 dark:fill-text-dark "}}
56
+ </div>
57
+ <div class="hidden">
58
+ <div class="px-4 py-2 font-bold text-white bg-red-500 rounded-t">
59
+ DEBUG
60
+ </div>
61
+ <div class="px-4 py-3 text-red-700 bg-red-100 border border-t-0 border-red-400 rounded-b">
62
+ <div>isFocused:<span x-text="isFocused" class="font-bold" :class="isFocused ? 'text-green-800' : 'text-red-700'"></span></div>
63
+ <div>wasFocused:<span x-text="wasFocused" class="font-bold" :class="wasFocused ? 'text-green-800' : 'text-red-700'"></span></div>
64
+ <div>valid:<span x-text="valid" class="font-bold" :class="valid ? 'text-green-800' : 'text-red-700'"></span></div>
65
+ <div>hideDescription:<span x-text="hideDescription()" class="font-bold" :class="hideDescription() ? 'text-green-800' : 'text-red-700'"></span></div>
66
+ <div>hideError:<span x-text="hideError()" class="font-bold" :class="hideError() ? 'text-green-800' : 'text-red-700'"></span></div>
67
+ <div>select:<span x-text="select{{getRandom}}" class="font-bold" ></span></div>
68
+ </div>
69
+ </div>
30
70
  </div>
@@ -0,0 +1,15 @@
1
+ export default function selectHandler(element) {
2
+ return {
3
+ [element]: '',
4
+ valid: false,
5
+ wasFocused: false,
6
+ isFocused: false,
7
+ validEmail: false,
8
+ hideDescription() {
9
+ return Boolean(!this.valid && this.wasFocused && !this.isFocused)
10
+ },
11
+ hideError() {
12
+ return Boolean(!this.hideDescription())
13
+ }
14
+ };
15
+ }