@luftborn/custom-elements 2.13.0 → 2.13.2

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 (73) hide show
  1. package/assets/style.css +10 -10
  2. package/demo/index.js +64 -44
  3. package/demo/index.min.js +63 -43
  4. package/demo/index.min.js.map +1 -1
  5. package/dist/elements/Address/AddressElement.js +1 -1
  6. package/dist/elements/Address/AddressElement.js.map +1 -1
  7. package/dist/elements/BankField/BankFieldElement.js +1 -1
  8. package/dist/elements/BankField/BankFieldElement.js.map +1 -1
  9. package/dist/elements/CPRElement/CPRElement.js +1 -1
  10. package/dist/elements/CPRElement/CPRElement.js.map +1 -1
  11. package/dist/elements/CVRElement/CVRElement.js +1 -1
  12. package/dist/elements/CVRElement/CVRElement.js.map +1 -1
  13. package/dist/elements/CheckBoxElement/CheckBoxElement.js +1 -1
  14. package/dist/elements/CheckBoxElement/CheckBoxElement.js.map +1 -1
  15. package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepicker.js +16 -13
  16. package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepicker.js.map +1 -1
  17. package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.d.ts +1 -1
  18. package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.js +1 -1
  19. package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.js.map +1 -1
  20. package/dist/elements/CustomFormatDateFieldElement/CustomFormatDateFieldElement.js +2 -2
  21. package/dist/elements/CustomFormatDateFieldElement/CustomFormatDateFieldElement.js.map +1 -1
  22. package/dist/elements/CustomRegularExpression/CustomRegularExpressionElement.js +1 -1
  23. package/dist/elements/CustomRegularExpression/CustomRegularExpressionElement.js.map +1 -1
  24. package/dist/elements/DateField/DateFieldElement.js +1 -1
  25. package/dist/elements/DateField/DateFieldElement.js.map +1 -1
  26. package/dist/elements/DropDownList/DropDownListElement.js +1 -1
  27. package/dist/elements/DropDownList/DropDownListElement.js.map +1 -1
  28. package/dist/elements/EmailField/EmailFieldElement.js +1 -1
  29. package/dist/elements/EmailField/EmailFieldElement.js.map +1 -1
  30. package/dist/elements/FileField/FileFieldElement.js +1 -1
  31. package/dist/elements/FileField/FileFieldElement.js.map +1 -1
  32. package/dist/elements/IdentificationElement/IdentificationElement.js +1 -1
  33. package/dist/elements/IdentificationElement/IdentificationElement.js.map +1 -1
  34. package/dist/elements/InternationaPhoneNumber/InternationaPhoneNumberElement.js +1 -1
  35. package/dist/elements/InternationaPhoneNumber/InternationaPhoneNumberElement.js.map +1 -1
  36. package/dist/elements/NumericField/NumericFieldElement.js +1 -1
  37. package/dist/elements/NumericField/NumericFieldElement.js.map +1 -1
  38. package/dist/elements/RadioButtonGroup/RadioButtonGroupElement.js +1 -1
  39. package/dist/elements/RadioButtonGroup/RadioButtonGroupElement.js.map +1 -1
  40. package/dist/elements/SECompanyRegistrationElement/SECompanyRegistrationElement.js +1 -1
  41. package/dist/elements/SECompanyRegistrationElement/SECompanyRegistrationElement.js.map +1 -1
  42. package/dist/elements/SEPersonalNumberElement/SEPersonalNumberElement.js +1 -1
  43. package/dist/elements/SEPersonalNumberElement/SEPersonalNumberElement.js.map +1 -1
  44. package/dist/elements/TextAreaElement/TextAreaElement.js +1 -1
  45. package/dist/elements/TextAreaElement/TextAreaElement.js.map +1 -1
  46. package/dist/elements/TextField/TextFieldElement.js +1 -1
  47. package/dist/elements/TextField/TextFieldElement.js.map +1 -1
  48. package/dist/elements/TypeAhead/TypeAheadElement.d.ts +3 -0
  49. package/dist/elements/TypeAhead/TypeAheadElement.js +26 -9
  50. package/dist/elements/TypeAhead/TypeAheadElement.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/elements/Address/AddressElement.ts +1 -1
  53. package/src/elements/BankField/BankFieldElement.ts +1 -1
  54. package/src/elements/CPRElement/CPRElement.ts +1 -1
  55. package/src/elements/CVRElement/CVRElement.ts +1 -1
  56. package/src/elements/CheckBoxElement/CheckBoxElement.ts +13 -5
  57. package/src/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepicker.ts +16 -13
  58. package/src/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.ts +18 -18
  59. package/src/elements/CustomFormatDateFieldElement/CustomFormatDateFieldElement.ts +16 -7
  60. package/src/elements/CustomRegularExpression/CustomRegularExpressionElement.ts +1 -1
  61. package/src/elements/DateField/DateFieldElement.ts +1 -1
  62. package/src/elements/DropDownList/DropDownListElement.ts +2 -2
  63. package/src/elements/EmailField/EmailFieldElement.ts +1 -1
  64. package/src/elements/FileField/FileFieldElement.ts +1 -1
  65. package/src/elements/IdentificationElement/IdentificationElement.ts +1 -1
  66. package/src/elements/InternationaPhoneNumber/InternationaPhoneNumberElement.ts +1 -1
  67. package/src/elements/NumericField/NumericFieldElement.ts +1 -1
  68. package/src/elements/RadioButtonGroup/RadioButtonGroupElement.ts +10 -5
  69. package/src/elements/SECompanyRegistrationElement/SECompanyRegistrationElement.ts +1 -1
  70. package/src/elements/SEPersonalNumberElement/SEPersonalNumberElement.ts +1 -1
  71. package/src/elements/TextAreaElement/TextAreaElement.ts +1 -1
  72. package/src/elements/TextField/TextFieldElement.ts +1 -1
  73. package/src/elements/TypeAhead/TypeAheadElement.ts +44 -22
@@ -8,8 +8,10 @@ import { defaultDateFormat, supportedDateFormats, validateDateString } from './C
8
8
  selector: 'custom-format-date-element',
9
9
  template: `
10
10
  <div class="wrapper">
11
- <input type="text" id="date-field" />
12
- <svg id="picker-trigger" data-toggle viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="4" width="20" height="18" rx="1" fill="#000"/><rect x="4" y="8" width="16" height="12" fill="white"/><path d="M4 10H20" stroke="#000" stroke-width="1"/><circle cx="16" cy="14" r="2" fill="#F44336"/><rect x="6" y="2" width="3" height="4" rx=".5" fill="#000"/><rect x="15" y="2" width="3" height="4" rx=".5" fill="#000"/></svg>
11
+ <input type="text" id="date-field">
12
+ <button id="picker-trigger" aria-label="Open date picker">
13
+ <svg class="svg-picker" data-toggle viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="4" width="20" height="18" rx="1" fill="#000"/><rect x="4" y="8" width="16" height="12" fill="white"/><path d="M4 10H20" stroke="#000" stroke-width="1"/><circle cx="16" cy="14" r="2" fill="#F44336"/><rect x="6" y="2" width="3" height="4" rx=".5" fill="#000"/><rect x="15" y="2" width="3" height="4" rx=".5" fill="#000"/></svg>
14
+ </button>
13
15
  </div>`,
14
16
  style: `
15
17
  :host{
@@ -27,21 +29,28 @@ import { defaultDateFormat, supportedDateFormats, validateDateString } from './C
27
29
  width: 100% !important;
28
30
  border: none;
29
31
  background-color: #f1f4ff;
30
- margin: 2px;
32
+ margin: 0.125rem;
31
33
  resize: none;
32
34
  }
33
35
  #date-field::after {
34
36
  content: url('path/to/datepicker-icon.png'); /* Path to your datepicker icon */
35
37
  cursor: pointer;
36
- right: 10px;
38
+ right: 0.625rem;
39
+ }
40
+ .svg-picker {
41
+ width: 0.938rem;
42
+ height: 0.938rem;
37
43
  }
38
44
  #picker-trigger {
39
45
  cursor: pointer;
40
- width: 15px;
41
- height: 15px;
46
+ background-color: transparent;
47
+ border: none;
48
+ width: 0.938rem;
49
+ height: 0.938rem;
42
50
  position:absolute;
43
- right: 2px;
51
+ right: 0.125rem;
44
52
  top: 15%;
53
+ padding: 0;
45
54
  }
46
55
  `,
47
56
  useShadow: true,
@@ -20,7 +20,7 @@ import { CustomElementEventArgs } from '../../framework/CustomEvents';
20
20
  width: 100% !important;
21
21
  border: none;
22
22
  background-color: #f1f4ff;
23
- margin: 2px;
23
+ margin: 0.125rem;
24
24
  resize: none;
25
25
  }
26
26
  `,
@@ -20,7 +20,7 @@ import { CustomElementEventArgs } from '../../framework/CustomEvents';
20
20
  width: 100% !important;
21
21
  border: none;
22
22
  background-color: #f1f4ff;
23
- margin: 2px;
23
+ margin: 0.125rem;
24
24
  resize: none;
25
25
  }
26
26
  `,
@@ -21,7 +21,7 @@ import { StringUtil } from '../../framework/Utilities/StringUtil';
21
21
  }
22
22
  .radio-button {
23
23
  width: auto;
24
- margin: auto 3px;
24
+ margin: auto 0.188rem;
25
25
  display: flex;
26
26
  flex-grow: 0.1;
27
27
  justify-content: space-around;
@@ -31,7 +31,7 @@ import { StringUtil } from '../../framework/Utilities/StringUtil';
31
31
  width: 100% !important;
32
32
  border: none;
33
33
  background-color: #f1f4ff;
34
- margin: 2px;
34
+ margin: 0.125rem;
35
35
  resize: none;
36
36
  }
37
37
  `,
@@ -20,7 +20,7 @@ import { CustomElementEventArgs } from '../../framework/CustomEvents';
20
20
  width: 100% !important;
21
21
  border: none;
22
22
  background-color: #f1f4ff;
23
- margin: 2px;
23
+ margin: 0.125rem;
24
24
  resize: none;
25
25
  }
26
26
  `,
@@ -22,7 +22,7 @@ import EXIF = require('exif-js');
22
22
  width: 100% !important;
23
23
  border: none;
24
24
  background-color: #f1f4ff;
25
- margin: 2px;
25
+ margin: 0.125rem;
26
26
  resize: none;
27
27
  }
28
28
  `,
@@ -30,7 +30,7 @@ import BankIdNorwayValidator from '../../framework/Validation/Validators/BankIdN
30
30
  box-sizing: border-box;
31
31
  border: none;
32
32
  background-color: #f1f4ff;
33
- margin: 2px;
33
+ margin: 0.125rem;
34
34
  resize: none;
35
35
  }
36
36
  input{
@@ -29,7 +29,7 @@ import GetFlags2XUrl from './Flags2x';
29
29
  width: 100% !important;
30
30
  border: none;
31
31
  background-color: #f1f4ff;
32
- margin: 2px;
32
+ margin: 0.125rem;
33
33
  resize: none;
34
34
  }
35
35
 
@@ -20,7 +20,7 @@ import { CustomElementEventArgs } from '../../framework/CustomEvents';
20
20
  width: 100% !important;
21
21
  border: none;
22
22
  background-color: #f1f4ff;
23
- margin: 2px;
23
+ margin: 0.125rem;
24
24
  resize: none;
25
25
  }
26
26
  `,
@@ -15,29 +15,34 @@ import { StringUtil } from '../../framework/Utilities/StringUtil';
15
15
  }
16
16
  .radio-button {
17
17
  width: auto;
18
- margin: auto 3px;
18
+ margin: auto 0.188rem;
19
19
  color: rgba(72, 72, 72, 0.75);
20
- font-size: 13px;
20
+ font-size: 0.813rem;
21
+ margin-top: 0.25rem;
22
+ }
23
+ .radio-button:first-of-type {
24
+ margin-top: 0;
21
25
  }
22
26
  input{
23
27
  box-sizing: border-box;
24
28
  width: auto !important;
25
29
  border: none;
26
30
  background-color: #f1f4ff;
27
- margin: 2px;
31
+ margin: 0.125rem;
28
32
  resize: none;
29
33
  }
30
34
  .sr-only:not(:focus):not(:active) {
31
35
  clip: rect(0 0 0 0);
32
36
  clip-path: inset(50%);
33
- height: 1px;
37
+ height: 0.063rem;
34
38
  overflow: hidden;
35
39
  position: absolute;
36
40
  white-space: nowrap;
37
- width: 1px;
41
+ width: 0.063rem;
38
42
  }
39
43
  fieldset {
40
44
  border: none;
45
+ padding: 0;
41
46
  }
42
47
  `,
43
48
  useShadow: true,
@@ -21,7 +21,7 @@ import SECompanyRegistrationValidator from '../../framework/Validation/Validator
21
21
  width: 100% !important;
22
22
  border: none;
23
23
  background-color: #f1f4ff;
24
- margin: 2px;
24
+ margin: 0.125rem;
25
25
  resize: none;
26
26
  }`,
27
27
  useShadow: true,
@@ -21,7 +21,7 @@ import SEPersonalNumberValidator from '../../framework/Validation/Validators/SEP
21
21
  width: 100% !important;
22
22
  border: none;
23
23
  background-color: #f1f4ff;
24
- margin: 2px;
24
+ margin: 0.125rem;
25
25
  resize: none;
26
26
  }`,
27
27
  useShadow: true,
@@ -20,7 +20,7 @@ import { CustomElementEventArgs } from '../../framework/CustomEvents';
20
20
  width: 100% !important;
21
21
  border: none;
22
22
  background-color: #f1f4ff;
23
- margin: 2px;
23
+ margin: 0.125rem;
24
24
  resize: none;
25
25
  }
26
26
  `,
@@ -20,7 +20,7 @@ import { CustomElementEventArgs } from '../../framework/CustomEvents';
20
20
  width: 100% !important;
21
21
  border: none;
22
22
  background-color: #f1f4ff;
23
- margin: 2px;
23
+ margin: 0.125rem;
24
24
  resize: none;
25
25
  }
26
26
  `,
@@ -7,9 +7,12 @@ import DomUtility from '../../framework/Utilities/DomUtility';
7
7
  @CustomElement({
8
8
  selector: 'type-ahead-element',
9
9
  template: `
10
- <div class="wrapper">
11
- <input type="text" id="text-input">
12
- <div id="description"></div>
10
+ <div class="wrapper" role="combobox" aria-expanded="false" aria-owns="options-list" aria-haspopup="listbox">
11
+ <input type="text" id="text-input" aria-autocomplete="list" aria-controls="options-list" aria-activedescendant="" role="textbox">
12
+ <div id="description" aria-live="polite"></div>
13
+ <div id="options-list" role="listbox" class="options-list" hidden>
14
+ <!-- Options will be dynamically added here -->
15
+ </div>
13
16
  </div>`,
14
17
  style: `
15
18
  :host {
@@ -27,45 +30,44 @@ import DomUtility from '../../framework/Utilities/DomUtility';
27
30
  width: 100% !important;
28
31
  border: none;
29
32
  background-color: #f1f4ff;
30
- margin: 2px;
33
+ margin: 0.125rem;
31
34
  resize: none;
32
35
  }
33
36
  .wrapper #description {
34
37
  width: 100%;
35
- padding: 0 2px;
38
+ padding: 0 0.125rem;
36
39
  box-sizing: border-box;
37
40
  }
38
41
  .options-list {
39
42
  position: absolute;
40
- border: 1px solid #E8E8E8;
43
+ border: 0.063rem solid #E8E8E8;
41
44
  border-bottom: none;
42
45
  border-top: none;
43
46
  z-index: 3;
44
47
  top: 100%;
45
48
  left: 0;
46
49
  right: 0;
47
- max-height: 200px;
50
+ max-height: 12.5rem;
48
51
  overflow-y: auto;
49
52
  }
50
53
  .options-list-item {
51
- padding: 10px;
54
+ padding: 0.625rem;
52
55
  cursor: pointer;
53
56
  background-color: #FFFFFF;
54
- border-bottom: 1px solid #E8E8E8;
57
+ border-bottom: 0.063rem solid #E8E8E8;
55
58
  }
56
59
  .options-list-item:hover {
57
60
  background-color: #E8E8E8;
58
61
  }
59
62
  .options-list-item.active {
60
- /*when navigating through the items using the arrow keys:*/
61
63
  background-color: #003E64 !important;
62
64
  color: #FFFFFF;
63
65
  }
64
66
  .options-list-item-title {
65
- font-size: 16px;
67
+ font-size: 1rem;
66
68
  }
67
69
  .options-list-item-description {
68
- font-size: 10px;
70
+ font-size: 0.625rem;
69
71
  }
70
72
  `,
71
73
  useShadow: true,
@@ -75,6 +77,7 @@ export class TypeAheadElement extends CustomInputElement {
75
77
  private textInputElement: HTMLInputElement;
76
78
  private descriptionElement: HTMLElement;
77
79
  private componentWrapper: HTMLElement;
80
+ private optionsListElement: HTMLElement;
78
81
  private currentFoucsedIndex = -1;
79
82
 
80
83
  selectedOption: OptionWithDescription;
@@ -123,14 +126,15 @@ export class TypeAheadElement extends CustomInputElement {
123
126
 
124
127
  initChildInputs() {
125
128
  this.textInputElement = super.getChildInput('#text-input');
126
- this.descriptionElement = super.getChildInput('#description');
129
+ this.descriptionElement = super.getChildElement('#description');
130
+ this.optionsListElement = super.getChildElement('#options-list');
127
131
  this.componentWrapper = super.getChildElement('.wrapper');
128
132
  if (this.required) {
129
133
  this.textInputElement.setAttribute('required', '');
130
134
  }
131
- if (this.placeholder) {
132
- this.textInputElement.setAttribute('placeholder', this.placeholder);
133
- }
135
+ if (this.placeholder) {
136
+ this.textInputElement.setAttribute('placeholder', this.placeholder);
137
+ }
134
138
  if (this.initialValue) {
135
139
  this.value = this.initialValue;
136
140
  }
@@ -169,6 +173,9 @@ export class TypeAheadElement extends CustomInputElement {
169
173
  }
170
174
  this.searchResultOptions.push(option);
171
175
  const optionsListItem = document.createElement("div");
176
+ optionsListItem.setAttribute('role', 'option');
177
+ optionsListItem.setAttribute('id', `option-${index}`);
178
+ optionsListItem.setAttribute('aria-selected', 'false');
172
179
  optionsListItem.classList.add('options-list-item');
173
180
  optionsListItem.dataset['value'] = option.value;
174
181
  optionslist.appendChild(optionsListItem);
@@ -183,17 +190,17 @@ export class TypeAheadElement extends CustomInputElement {
183
190
  optionsListItem.addEventListener('mousedown', () => {
184
191
  this.optionSelectedHandler(option);
185
192
  });
186
- this.componentWrapper.appendChild(optionslist);
193
+ this.optionsListElement.appendChild(optionsListItem);
187
194
  });
195
+ this.optionsListElement.hidden = false;
196
+ this.updateAriaAttributes();
188
197
  }
189
198
 
190
199
  private closeOptionsList() {
191
200
  this.currentFoucsedIndex = -1;
192
- const optionsList = super.getChildElement('.options-list');
193
- if (!optionsList) {
194
- return;
195
- }
196
- optionsList.remove();
201
+ this.optionsListElement.innerHTML = '';
202
+ this.optionsListElement.hidden = true;
203
+ this.updateAriaAttributes();
197
204
  }
198
205
 
199
206
  private optionSelectedHandler(option: OptionWithDescription) {
@@ -213,6 +220,7 @@ export class TypeAheadElement extends CustomInputElement {
213
220
  }
214
221
  this.currentFoucsedIndex = this.currentFoucsedIndex === this.searchResultOptions.length - 1 ? 0 : this.currentFoucsedIndex + 1;
215
222
  this.highlightFocusedSearchResult();
223
+ this.scrollToFocusedOption();
216
224
  }
217
225
  if (event.key === 'ArrowUp') {
218
226
  if (!this.searchHasResults) {
@@ -220,6 +228,7 @@ export class TypeAheadElement extends CustomInputElement {
220
228
  }
221
229
  this.currentFoucsedIndex = this.currentFoucsedIndex === 0 ? this.searchResultOptions.length - 1 : this.currentFoucsedIndex - 1;
222
230
  this.highlightFocusedSearchResult();
231
+ this.scrollToFocusedOption();
223
232
  }
224
233
  if (event.key === 'Enter') {
225
234
  if (this.currentFoucsedIndex !== -1 && this.searchHasResults) {
@@ -230,19 +239,32 @@ export class TypeAheadElement extends CustomInputElement {
230
239
  });
231
240
  }
232
241
 
242
+ private scrollToFocusedOption() {
243
+ const optionListItems = super.getChildElements('.options-list-item');
244
+ if (optionListItems && optionListItems[this.currentFoucsedIndex]) {
245
+ optionListItems[this.currentFoucsedIndex].scrollIntoView({ block: 'nearest' });
246
+ }
247
+ }
248
+
233
249
  highlightFocusedSearchResult() {
234
250
  const optionListItems = super.getChildElements('.options-list-item');
235
251
  if (!optionListItems) {
236
252
  return;
237
253
  }
238
254
  optionListItems.forEach((listItem, index) => {
255
+ listItem.setAttribute('aria-selected', String(index === this.currentFoucsedIndex));
239
256
  listItem.classList.remove('active');
240
257
  if (index === this.currentFoucsedIndex) {
241
258
  listItem.classList.add('active');
259
+ this.textInputElement.setAttribute('aria-activedescendant', listItem.id);
242
260
  }
243
261
  });
244
262
  }
245
263
 
264
+ private updateAriaAttributes() {
265
+ this.textInputElement.setAttribute('aria-expanded', String(!this.optionsListElement.hidden));
266
+ }
267
+
246
268
  public change($event): void {
247
269
  this.touched = true;
248
270
  this.onChange.emit(new CustomElementEventArgs(this.value, 'change'));