hr-design-system-handlebars 1.101.2 → 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,28 @@
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
+
13
+ # v1.101.3 (Tue Sep 24 2024)
14
+
15
+ #### ⚠️ Pushed to `main`
16
+
17
+ - Merge branch 'main' of https://github.com/mumprod/hr-design-system-handlebars into main ([@vascoeduardo](https://github.com/vascoeduardo))
18
+ - ✨ DPE-3290 Dropdown ([@vascoeduardo](https://github.com/vascoeduardo))
19
+
20
+ #### Authors: 1
21
+
22
+ - Vasco ([@vascoeduardo](https://github.com/vascoeduardo))
23
+
24
+ ---
25
+
1
26
  # v1.101.2 (Mon Sep 23 2024)
2
27
 
3
28
  #### 🐛 Bug Fix
@@ -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-8, .-rotate-45, .rotate-180, .rotate-45, .scale-50, .scale-75, .scale-y-100, .scale-y-90, .transform, .is-loading::after, .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\: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;
@@ -1157,6 +1157,12 @@ article.indexTextDS .indexTextHighlighted .link {
1157
1157
  .top-0\.5 {
1158
1158
  top: 0.125rem;
1159
1159
  }
1160
+ .top-1 {
1161
+ top: 0.25rem;
1162
+ }
1163
+ .top-1\.5 {
1164
+ top: 0.375rem;
1165
+ }
1160
1166
  .top-1\/2 {
1161
1167
  top: 50%;
1162
1168
  }
@@ -1922,6 +1928,10 @@ article.indexTextDS .indexTextHighlighted .link {
1922
1928
  --tw-translate-y: 3rem;
1923
1929
  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));
1924
1930
  }
1931
+ .translate-y-3 {
1932
+ --tw-translate-y: 0.75rem;
1933
+ 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));
1934
+ }
1925
1935
  .translate-y-8 {
1926
1936
  --tw-translate-y: 2rem;
1927
1937
  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));
@@ -1938,6 +1948,11 @@ article.indexTextDS .indexTextHighlighted .link {
1938
1948
  --tw-rotate: 45deg;
1939
1949
  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));
1940
1950
  }
1951
+ .scale-100 {
1952
+ --tw-scale-x: 1;
1953
+ --tw-scale-y: 1;
1954
+ 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));
1955
+ }
1941
1956
  .scale-50 {
1942
1957
  --tw-scale-x: .5;
1943
1958
  --tw-scale-y: .5;
@@ -2452,6 +2467,10 @@ article.indexTextDS .indexTextHighlighted .link {
2452
2467
  --tw-bg-opacity: 1;
2453
2468
  background-color: rgba(243, 244, 246, var(--tw-bg-opacity));
2454
2469
  }
2470
+ .bg-gray-400 {
2471
+ --tw-bg-opacity: 1;
2472
+ background-color: rgba(156, 163, 175, var(--tw-bg-opacity));
2473
+ }
2455
2474
  .bg-gray-500 {
2456
2475
  --tw-bg-opacity: 1;
2457
2476
  background-color: rgba(107, 114, 128, var(--tw-bg-opacity));
@@ -2641,6 +2660,9 @@ article.indexTextDS .indexTextHighlighted .link {
2641
2660
  .fill-\[\#606060\] {
2642
2661
  fill: #606060;
2643
2662
  }
2663
+ .fill-blue-500 {
2664
+ fill: #3b82f6;
2665
+ }
2644
2666
  .fill-blue-congress-hex {
2645
2667
  fill: #005293;
2646
2668
  }
@@ -3454,7 +3476,7 @@ article.indexTextDS .indexTextHighlighted .link {
3454
3476
  border-bottom-color: var(--color-secondary-ds);
3455
3477
  }
3456
3478
  .counter-reset {
3457
- counter-reset: cnt1727102904220;
3479
+ counter-reset: cnt1727170647026;
3458
3480
  }
3459
3481
  .hyphens-auto {
3460
3482
  -webkit-hyphens: auto;
@@ -3862,7 +3884,7 @@ article.indexTextDS .indexTextHighlighted .link {
3862
3884
  --tw-ring-color: rgba(255, 255, 255, 0.5);
3863
3885
  }
3864
3886
  .-ordered {
3865
- counter-increment: cnt1727102904220 1;
3887
+ counter-increment: cnt1727170647026 1;
3866
3888
  }
3867
3889
  .-ordered::before {
3868
3890
  position: absolute;
@@ -3878,7 +3900,7 @@ article.indexTextDS .indexTextHighlighted .link {
3878
3900
  letter-spacing: .0125em;
3879
3901
  --tw-text-opacity: 1;
3880
3902
  color: rgba(0, 0, 0, var(--tw-text-opacity));
3881
- content: counter(cnt1727102904220);
3903
+ content: counter(cnt1727170647026);
3882
3904
  }
3883
3905
  /*! ****************************/
3884
3906
  /*! DataPolicy stuff */
@@ -3977,6 +3999,30 @@ article.indexTextDS .indexTextHighlighted .link {
3977
3999
  ul.restrictedToTwo li:nth-of-type(1n + 2) .timelineBorder {
3978
4000
  display: none;
3979
4001
  }
4002
+ /*! ****************************/
4003
+ /*! FORMULAR SELECT */
4004
+ /*! ****************************/
4005
+ /* Custom CSS to style the label when the first empty option is selected */
4006
+ select[\:has\(option\:checked\:not\(\[value\%3D\%22\%22\]\)\)] + label {
4007
+ top: 1px;
4008
+ --tw-translate-y: 0px;
4009
+ --tw-scale-x: .75;
4010
+ --tw-scale-y: .75;
4011
+ 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));
4012
+ }
4013
+ select:has(option:checked:not([value=""])) + label {
4014
+ top: 1px;
4015
+ --tw-translate-y: 0px;
4016
+ --tw-scale-x: .75;
4017
+ --tw-scale-y: .75;
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));
4019
+ }
4020
+ select[\:has\(option\:checked\[value\%3D\%22\%22\]\)] {
4021
+ color: transparent;
4022
+ }
4023
+ select:has(option:checked[value=""]) {
4024
+ color: transparent;
4025
+ }
3980
4026
  .\[-T\:\+Z\] {
3981
4027
  --t: +Z;
3982
4028
  }
@@ -5939,6 +5985,9 @@ ul.restrictedToTwo li:nth-of-type(1n + 2) .timelineBorder {
5939
5985
  --tw-scale-y: 1;
5940
5986
  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));
5941
5987
  }
5988
+ .peer:focus ~ .peer-focus\:top-px {
5989
+ top: 1px;
5990
+ }
5942
5991
  .peer:focus ~ .peer-focus\:-translate-y-0 {
5943
5992
  --tw-translate-y: -0px;
5944
5993
  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));
@@ -5947,11 +5996,25 @@ ul.restrictedToTwo li:nth-of-type(1n + 2) .timelineBorder {
5947
5996
  --tw-translate-x: 0px;
5948
5997
  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));
5949
5998
  }
5999
+ .peer:focus ~ .peer-focus\:translate-y-0 {
6000
+ --tw-translate-y: 0px;
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));
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
+ }
5950
6007
  .peer:focus ~ .peer-focus\:scale-75 {
5951
6008
  --tw-scale-x: .75;
5952
6009
  --tw-scale-y: .75;
5953
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));
5954
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
+ }
5955
6018
  .peer:focus ~ .peer-focus\:text-blue-500 {
5956
6019
  --tw-text-opacity: 1;
5957
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
+ }
@@ -47,13 +47,14 @@
47
47
  _errorEmail="Bitte geben Sie eine gültige E-Mail-Adresse ein."
48
48
  }}
49
49
  {{else if this.type.isSelect}}
50
- {{~> modules/forms/select
50
+ {{~> components/forms/select
51
51
  _name=this.name
52
52
  _label=this.label
53
53
  _labelClass="hide"
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 }}
@@ -0,0 +1,70 @@
1
+ <div class="relative flex flex-col w-full mb-5 "
2
+ ax-load
3
+ x-data="selectHandler('select{{nextRandom}}')"
4
+ x-ignore
5
+ >
6
+ <select
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}}
38
+ </select>
39
+ <label for="select{{getRandom}}"
40
+ class="absolute pointer-events-none left-[16px] top-0 translate-y-3 translate-x-0 scale-100 text-gray-500
41
+ peer-focus:text-blue-500 peer-focus:scale-75 peer-focus:translate-y-0 peer-focus:top-px
42
+ origin-top-left transform transition-transform
43
+ ">
44
+ {{_label}}{{#if _required}}*{{/if}}
45
+ </label>
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}}
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>
70
+ </div>
@@ -47,13 +47,14 @@
47
47
  _errorEmail="Bitte geben Sie eine gültige E-Mail-Adresse ein."
48
48
  }}
49
49
  {{else if this.type.isSelect}}
50
- {{~> modules/forms/select
50
+ {{~> components/forms/select
51
51
  _name=this.name
52
52
  _label=this.label
53
53
  _labelClass="hide"
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 }}
@@ -0,0 +1,70 @@
1
+ <div class="relative flex flex-col w-full mb-5 "
2
+ ax-load
3
+ x-data="selectHandler('select{{nextRandom}}')"
4
+ x-ignore
5
+ >
6
+ <select
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}}
38
+ </select>
39
+ <label for="select{{getRandom}}"
40
+ class="absolute pointer-events-none left-[16px] top-0 translate-y-3 translate-x-0 scale-100 text-gray-500
41
+ peer-focus:text-blue-500 peer-focus:scale-75 peer-focus:translate-y-0 peer-focus:top-px
42
+ origin-top-left transform transition-transform
43
+ ">
44
+ {{_label}}{{#if _required}}*{{/if}}
45
+ </label>
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}}
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>
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.2",
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",
@@ -446,4 +446,17 @@
446
446
  ul.restrictedToTwo li:nth-of-type(1n + 2) .timelineBorder {
447
447
  display: none;
448
448
  }
449
+ /*! ****************************/
450
+ /*! FORMULAR SELECT */
451
+ /*! ****************************/
452
+ /* Custom CSS to style the label when the first empty option is selected */
453
+ select:has(option:checked:not([value=""])) + label{
454
+ @apply top-px scale-75 translate-y-0
455
+ }
456
+
457
+ select:has(option:checked[value=""]) {
458
+ @apply text-transparent
459
+ }
460
+
461
+
449
462
  }
@@ -1,90 +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
89
- }
90
- }
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
82
+ },
83
+ "select": {
84
+ "type": {
85
+ "isSelect": true,
86
+ "asString": "select"
87
+ },
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
+ }
@@ -0,0 +1,18 @@
1
+ {
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
+ }
15
+ ]
16
+ }
17
+ ]
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
@@ -47,13 +47,14 @@
47
47
  _errorEmail="Bitte geben Sie eine gültige E-Mail-Adresse ein."
48
48
  }}
49
49
  {{else if this.type.isSelect}}
50
- {{~> modules/forms/select
50
+ {{~> components/forms/select
51
51
  _name=this.name
52
52
  _label=this.label
53
53
  _labelClass="hide"
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 }}
@@ -0,0 +1 @@
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"}]}]}
@@ -4,6 +4,8 @@ import inputMandatoryJson from './fixtures/form_input_mandatory.json'
4
4
  import inputPrefilledJson from './fixtures/form_input_prefilled.json'
5
5
  import textareaJson from './fixtures/form_textarea.json'
6
6
  import emailJson from './fixtures/form_email.json'
7
+ import selectJson from './fixtures/form_select.json'
8
+
7
9
 
8
10
  const handlebars = require('hrHandlebars')
9
11
 
@@ -66,4 +68,9 @@ export const Textarea = {
66
68
  render: Template.bind({}),
67
69
  name: 'Textarea',
68
70
  args: textareaJson,
69
- }
71
+ }
72
+ export const Select = {
73
+ render: Template.bind({}),
74
+ name: 'Select',
75
+ args: selectJson,
76
+ }
@@ -0,0 +1,70 @@
1
+ <div class="relative flex flex-col w-full mb-5 "
2
+ ax-load
3
+ x-data="selectHandler('select{{nextRandom}}')"
4
+ x-ignore
5
+ >
6
+ <select
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}}
38
+ </select>
39
+ <label for="select{{getRandom}}"
40
+ class="absolute pointer-events-none left-[16px] top-0 translate-y-3 translate-x-0 scale-100 text-gray-500
41
+ peer-focus:text-blue-500 peer-focus:scale-75 peer-focus:translate-y-0 peer-focus:top-px
42
+ origin-top-left transform transition-transform
43
+ ">
44
+ {{_label}}{{#if _required}}*{{/if}}
45
+ </label>
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}}
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>
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
+ }