@iamproperty/components 7.8.2--beta2 → 7.8.2--beta4

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 (206) hide show
  1. package/assets/css/components/actionbar.component.css +1 -1
  2. package/assets/css/components/actionbar.component.css.map +1 -1
  3. package/assets/css/components/address-lookup.component.css +1 -1
  4. package/assets/css/components/address-lookup.component.css.map +1 -1
  5. package/assets/css/components/advanced-select.component.css +1 -1
  6. package/assets/css/components/advanced-select.component.css.map +1 -1
  7. package/assets/css/components/applied-filters.css +1 -1
  8. package/assets/css/components/applied-filters.css.map +1 -1
  9. package/assets/css/components/banner.preload.css +1 -0
  10. package/assets/css/components/banner.preload.css.map +1 -0
  11. package/assets/css/components/calendar.component.css +1 -1
  12. package/assets/css/components/calendar.component.css.map +1 -1
  13. package/assets/css/components/card.component.css +1 -1
  14. package/assets/css/components/card.component.css.map +1 -1
  15. package/assets/css/components/card.module.css +1 -1
  16. package/assets/css/components/card.module.css.map +1 -1
  17. package/assets/css/components/card.preload.css +1 -0
  18. package/assets/css/components/card.preload.css.map +1 -0
  19. package/assets/css/components/carousel.component.css +1 -1
  20. package/assets/css/components/carousel.component.css.map +1 -1
  21. package/assets/css/components/carousel.config.css +1 -1
  22. package/assets/css/components/carousel.config.css.map +1 -1
  23. package/assets/css/components/config.component.css +1 -1
  24. package/assets/css/components/config.component.css.map +1 -1
  25. package/assets/css/components/content.component.css +1 -1
  26. package/assets/css/components/content.component.css.map +1 -1
  27. package/assets/css/components/fileupload.css +1 -1
  28. package/assets/css/components/fileupload.css.map +1 -1
  29. package/assets/css/components/filter-card.component.css +1 -1
  30. package/assets/css/components/filter-card.component.css.map +1 -1
  31. package/assets/css/components/multiselect.css +1 -1
  32. package/assets/css/components/multiselect.css.map +1 -1
  33. package/assets/css/components/nav.component.css +1 -1
  34. package/assets/css/components/nav.component.css.map +1 -1
  35. package/assets/css/components/pagination.css +1 -1
  36. package/assets/css/components/pagination.css.map +1 -1
  37. package/assets/css/components/record-card.component.css +1 -1
  38. package/assets/css/components/record-card.component.css.map +1 -1
  39. package/assets/css/components/search.component.css +1 -1
  40. package/assets/css/components/search.component.css.map +1 -1
  41. package/assets/css/components/skeleton.global.css +1 -1
  42. package/assets/css/components/skeleton.global.css.map +1 -1
  43. package/assets/css/components/slider.css +1 -1
  44. package/assets/css/components/slider.css.map +1 -1
  45. package/assets/css/components/split-button.component.css +1 -1
  46. package/assets/css/components/split-button.component.css.map +1 -1
  47. package/assets/css/components/std-nav-standalone.component.css +1 -1
  48. package/assets/css/components/std-nav-standalone.component.css.map +1 -1
  49. package/assets/css/components/tabs.component.css +1 -1
  50. package/assets/css/components/tabs.component.css.map +1 -1
  51. package/assets/css/components/tag.component.css +1 -1
  52. package/assets/css/components/tag.component.css.map +1 -1
  53. package/assets/css/components/video-card.component.css +1 -1
  54. package/assets/css/components/video-card.component.css.map +1 -1
  55. package/assets/css/core.min.css +1 -1
  56. package/assets/css/core.min.css.map +1 -1
  57. package/assets/css/elements/badge-tag.css +1 -1
  58. package/assets/css/elements/badge-tag.css.map +1 -1
  59. package/assets/css/elements/dropdown.css +1 -1
  60. package/assets/css/elements/dropdown.css.map +1 -1
  61. package/assets/css/elements/forms.css +1 -1
  62. package/assets/css/elements/forms.css.map +1 -1
  63. package/assets/css/elements/links--global.css +1 -1
  64. package/assets/css/elements/links--global.css.map +1 -1
  65. package/assets/css/elements/links.css +1 -1
  66. package/assets/css/elements/links.css.map +1 -1
  67. package/assets/css/style.min.css +1 -1
  68. package/assets/css/style.min.css.map +1 -1
  69. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  70. package/assets/js/components/actionbar/actionbar.component.min.js +2 -2
  71. package/assets/js/components/address-lookup/address-lookup.component.min.js +4 -4
  72. package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
  73. package/assets/js/components/advanced-select/advanced-select.component.min.js +2 -2
  74. package/assets/js/components/applied-filters/applied-filters.component.min.js +2 -2
  75. package/assets/js/components/banner/banner.component.min.js +1 -1
  76. package/assets/js/components/barchart/barchart.component.min.js +1 -1
  77. package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
  78. package/assets/js/components/bone/bone.component.min.js +1 -1
  79. package/assets/js/components/button/button.component.min.js +1 -1
  80. package/assets/js/components/calendar/calendar.component.min.js +2 -2
  81. package/assets/js/components/card/card.component.js +114 -125
  82. package/assets/js/components/card/card.component.min.js +7 -7
  83. package/assets/js/components/card/card.component.min.js.map +1 -1
  84. package/assets/js/components/carousel/carousel.component.js +83 -29
  85. package/assets/js/components/carousel/carousel.component.min.js +16 -11
  86. package/assets/js/components/carousel/carousel.component.min.js.map +1 -1
  87. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  88. package/assets/js/components/config/config.component.min.js +7 -7
  89. package/assets/js/components/config/config.component.min.js.map +1 -1
  90. package/assets/js/components/content/content.component.js +28 -69
  91. package/assets/js/components/content/content.component.min.js +4 -4
  92. package/assets/js/components/content/content.component.min.js.map +1 -1
  93. package/assets/js/components/darkmode/darkmode.component.min.js +1 -1
  94. package/assets/js/components/doughnutchart/doughnutchart.component.min.js +1 -1
  95. package/assets/js/components/fileupload/fileupload.component.min.js +2 -2
  96. package/assets/js/components/filter-card/filter-card.component.min.js +5 -5
  97. package/assets/js/components/filter-card/filter-card.component.min.js.map +1 -1
  98. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  99. package/assets/js/components/form/form.component.min.js +1 -1
  100. package/assets/js/components/header/header.component.min.js +1 -1
  101. package/assets/js/components/inline-edit/inline-edit.component.min.js +1 -1
  102. package/assets/js/components/input/input.component.min.js +1 -1
  103. package/assets/js/components/input-range/input-range.component.min.js +1 -1
  104. package/assets/js/components/marketing/marketing.component.min.js +1 -1
  105. package/assets/js/components/menu/menu.component.min.js +1 -1
  106. package/assets/js/components/milestone/milestone.component.min.js +1 -1
  107. package/assets/js/components/milestone-group/milestone-group.component.min.js +1 -1
  108. package/assets/js/components/modal/modal.component.min.js +1 -1
  109. package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
  110. package/assets/js/components/multi-step-modal/multi-step-modal.component.min.js +1 -1
  111. package/assets/js/components/multiselect/multiselect.component.min.js +4 -4
  112. package/assets/js/components/multiselect/multiselect.component.min.js.map +1 -1
  113. package/assets/js/components/nav/nav.component.min.js +2 -2
  114. package/assets/js/components/notification/notification.component.min.js +1 -1
  115. package/assets/js/components/pagination/pagination.component.min.js +5 -5
  116. package/assets/js/components/password/password.component.min.js +1 -1
  117. package/assets/js/components/popover/popover.component.min.js +1 -1
  118. package/assets/js/components/rank/rank.component.min.js +1 -1
  119. package/assets/js/components/rankings/rankings.component.min.js +1 -1
  120. package/assets/js/components/rating/rating.component.min.js +1 -1
  121. package/assets/js/components/record-card/record-card.component.min.js +6 -6
  122. package/assets/js/components/record-card/record-card.component.min.js.map +1 -1
  123. package/assets/js/components/search/search.component.js +234 -186
  124. package/assets/js/components/search/search.component.min.js +12 -7
  125. package/assets/js/components/search/search.component.min.js.map +1 -1
  126. package/assets/js/components/skeleton/skeleton.component.min.js +1 -1
  127. package/assets/js/components/slider/slider.component.min.js +2 -2
  128. package/assets/js/components/split-button/split-button.component.min.js +2 -2
  129. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js +5 -5
  130. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js.map +1 -1
  131. package/assets/js/components/std-nav/std-nav.component.js +10 -9
  132. package/assets/js/components/std-nav/std-nav.component.min.js +9 -12
  133. package/assets/js/components/std-nav/std-nav.component.min.js.map +1 -1
  134. package/assets/js/components/std-nav-standalone/std-nav-standalone.component.min.js +5 -5
  135. package/assets/js/components/std-nav-standalone/std-nav-standalone.component.min.js.map +1 -1
  136. package/assets/js/components/table/table.component.min.js +1 -1
  137. package/assets/js/components/table-ajax/table-ajax.component.min.js +1 -1
  138. package/assets/js/components/table-basic/table-basic.component.min.js +1 -1
  139. package/assets/js/components/table-no-submit/table-no-submit.component.min.js +1 -1
  140. package/assets/js/components/table-submit/table-submit.component.min.js +1 -1
  141. package/assets/js/components/tabs/tabs.component.min.js +4 -4
  142. package/assets/js/components/tag/tag.component.min.js +3 -3
  143. package/assets/js/components/tag/tag.component.min.js.map +1 -1
  144. package/assets/js/components/tooltip/tooltip.component.min.js +1 -1
  145. package/assets/js/components/video/video.component.min.js +1 -1
  146. package/assets/js/components/video-card/video-card.component.min.js +9 -9
  147. package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
  148. package/assets/js/components/video-modal/video-modal.component.min.js +1 -1
  149. package/assets/js/components/word-count/word-count.component.min.js +1 -1
  150. package/assets/js/modules/card.module.js +12 -11
  151. package/assets/js/modules/content.js +40 -8
  152. package/assets/js/modules/content.test.js +62 -12
  153. package/assets/js/modules/data-layer.js +7 -6
  154. package/assets/js/modules/dropdown.js +0 -1
  155. package/assets/js/modules/nav.js +10 -3
  156. package/assets/js/modules/search.js +153 -0
  157. package/assets/js/modules/search.test.js +125 -0
  158. package/assets/js/modules/tabs.test.js +64 -12
  159. package/assets/js/modules/testimonial.test.js +44 -6
  160. package/assets/js/modules/videos.test.js +61 -13
  161. package/assets/js/scripts.bundle.js +3 -3
  162. package/assets/js/scripts.bundle.js.map +1 -1
  163. package/assets/js/scripts.bundle.min.js +2 -2
  164. package/assets/js/scripts.bundle.min.js.map +1 -1
  165. package/assets/sass/_components.scss +2 -63
  166. package/assets/sass/components/banner.preload.scss +26 -0
  167. package/assets/sass/components/card.component.scss +1 -7
  168. package/assets/sass/components/card.module.scss +6 -6
  169. package/assets/sass/components/card.preload.scss +80 -0
  170. package/assets/sass/components/carousel.component.scss +165 -0
  171. package/assets/sass/components/carousel.config.scss +85 -249
  172. package/assets/sass/components/content.component.scss +0 -7
  173. package/assets/sass/components/nav.component.scss +2 -1
  174. package/assets/sass/components/search.component.scss +89 -7
  175. package/assets/sass/components/skeleton.global.scss +4 -0
  176. package/assets/sass/elements/badge-tag.css +1 -1
  177. package/assets/sass/elements/dropdown.css +2 -0
  178. package/assets/sass/elements/forms.scss +0 -27
  179. package/assets/sass/elements/links--global.scss +40 -2
  180. package/assets/sass/foundations/root.scss +0 -1
  181. package/assets/sass/utilities/border.css +1 -1
  182. package/assets/sass/utilities/js-display.css +2 -3
  183. package/assets/ts/components/card/card.component.ts +72 -62
  184. package/assets/ts/components/carousel/carousel.component.ts +84 -19
  185. package/assets/ts/components/content/content.component.ts +36 -100
  186. package/assets/ts/components/search/search.component.ts +257 -185
  187. package/assets/ts/components/std-nav/std-nav.component.ts +17 -16
  188. package/assets/ts/html.d.ts +6 -0
  189. package/assets/ts/modules/card.module.ts +20 -12
  190. package/assets/ts/modules/content.test.ts +84 -12
  191. package/assets/ts/modules/content.ts +56 -9
  192. package/assets/ts/modules/data-layer.ts +7 -11
  193. package/assets/ts/modules/dropdown.ts +0 -2
  194. package/assets/ts/modules/nav.ts +12 -3
  195. package/assets/ts/modules/search.test.ts +142 -0
  196. package/assets/ts/modules/search.ts +206 -0
  197. package/assets/ts/modules/tabs.test.ts +79 -12
  198. package/assets/ts/modules/testimonial.test.ts +45 -6
  199. package/assets/ts/modules/videos.test.ts +74 -14
  200. package/dist/components.es.js +25 -25
  201. package/dist/components.umd.js +164 -157
  202. package/package.json +1 -1
  203. package/assets/js/modules/carousel.js +0 -214
  204. package/assets/js/modules/carousel.test.js +0 -18
  205. package/assets/ts/modules/carousel.test.ts +0 -27
  206. package/assets/ts/modules/carousel.ts +0 -301
@@ -1,216 +1,264 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
1
+ import search, { filterDatalist, datalistSelectOption } from '../../modules/search';
2
+ const getIntegerAttribute = (element, attributeName, fallback) => {
3
+ const value = Number.parseInt(element.getAttribute(attributeName) || '', 10);
4
+ return Number.isNaN(value) ? fallback : value;
9
5
  };
10
- import Cookies from '../../../../node_modules/js-cookie/dist/js.cookie.mjs';
11
- import { safeID, resolvePath, isTraversable } from '../../modules/helpers';
12
- import advancedSelect from '../../modules/advanced-select';
6
+ const getOptionFromEvent = (event) => event.target instanceof HTMLElement ? event.target.closest('option') : null;
13
7
  // Data layer Web component created
14
- window.dataLayer = window.dataLayer || [];
15
- window.dataLayer.push({
8
+ const searchWindow = window;
9
+ searchWindow.dataLayer = searchWindow.dataLayer || [];
10
+ searchWindow.dataLayer.push({
16
11
  event: 'customElementRegistered',
17
12
  element: 'Search',
18
13
  });
19
14
  class iamSearch extends HTMLElement {
20
15
  constructor() {
21
16
  super();
22
- this.attachShadow({ mode: 'open' });
23
- const assetLocation = document.body.hasAttribute('data-assets-location')
24
- ? document.body.getAttribute('data-assets-location')
25
- : '/assets';
17
+ const shadowRoot = this.attachShadow({ mode: 'open' });
18
+ const assetLocation = document.body.getAttribute('data-assets-location') || '/assets';
26
19
  const loadCSS = `@import "${assetLocation}/css/components/search.component.css";`;
27
20
  const template = document.createElement('template');
28
- template.innerHTML = `
21
+ template.innerHTML = /* HTML */ `
29
22
  <style>
30
23
  ${loadCSS}
31
24
  </style>
32
25
  <link rel="stylesheet" href="https://kit.fontawesome.com/8bd0fca975.css" crossorigin="anonymous" />
33
- <span class="wrapper"><span class="input__wrapper"><slot></slot></span><span class="suffix fa-regular fa-search"></span></span>
26
+ <span class="wrapper">
27
+ <span class="input__wrapper">
28
+ <slot></slot>
29
+ <button class="clear-search btn btn-action" type="button"><i class="fa-light fa-times me-0"></i></button>
30
+ </span>
31
+ <button class="suffix ${this.getAttribute('data-icon') || 'fa-regular fa-search'}"></button>
32
+ </span>
34
33
  <slot name="datalist"></slot>
35
34
  `;
36
- this.shadowRoot.appendChild(template.content.cloneNode(true));
35
+ shadowRoot.appendChild(template.content.cloneNode(true));
37
36
  }
38
37
  connectedCallback() {
39
- return __awaiter(this, void 0, void 0, function* () {
40
- // Make the datalist a dropdown
41
- this.classList.add('dropdown__wrapper');
42
- if (this.querySelector('input.input--sm'))
43
- this.classList.add('hasInputSm');
44
- if (this.querySelector('label'))
45
- this.classList.add('has-label');
46
- // eslint-disable-next-line @typescript-eslint/no-this-alias
47
- const searchWrapper = this;
48
- const inputField = this.querySelector('input');
49
- const valueSchema = this.hasAttribute('data-value-schema') ? this.getAttribute('data-value-schema') : 'value';
50
- const displaySchema = this.hasAttribute('data-display-schema') ? this.getAttribute('data-display-schema') : 'label';
51
- const loopSchema = this.hasAttribute('data-schema') ? this.getAttribute('data-schema') : '';
52
- let datalist = this.querySelector('datalist');
53
- let minLength = this.hasAttribute('data-min-length') ? this.getAttribute('data-min-length') : 0;
54
- if (searchWrapper.hasAttribute('data-url') && !this.hasAttribute('data-min-length')) {
55
- minLength = 3;
38
+ const shadowRoot = this.shadowRoot;
39
+ if (!shadowRoot)
40
+ return;
41
+ let datalistElement = this.querySelector('datalist');
42
+ const inputElement = this.querySelector('input');
43
+ const suffixElement = shadowRoot.querySelector('.suffix');
44
+ const clearBtn = shadowRoot.querySelector('.clear-search');
45
+ let minLength = this.hasAttribute('data-min-length') ? getIntegerAttribute(this, 'data-min-length', 1) : 1;
46
+ if (this.hasAttribute('data-url') && !this.hasAttribute('data-min-length')) {
47
+ minLength = 3;
48
+ }
49
+ if (!inputElement || !suffixElement)
50
+ return;
51
+ // #region maintain the original placeholder value in a data attribute to allow for it to be reset when the field is emptied
52
+ const originalPlaceholder = inputElement.getAttribute('placeholder');
53
+ if (originalPlaceholder !== null)
54
+ this.setAttribute('data-original-placeholder', originalPlaceholder);
55
+ // #endregion
56
+ // #region transform datalist into dropdown
57
+ // Turn off the browser's default datalist functionality to allow for a custom implementation
58
+ inputElement.setAttribute('autocomplete', 'off');
59
+ inputElement.setAttribute('aria-autocomplete', 'none');
60
+ if (inputElement && inputElement.hasAttribute('list')) {
61
+ inputElement.setAttribute('data-list', inputElement.getAttribute('list') || '');
62
+ inputElement.setAttribute('list', '');
63
+ }
64
+ if (!datalistElement) {
65
+ datalistElement = document.createElement('datalist');
66
+ const listID = `${inputElement === null || inputElement === void 0 ? void 0 : inputElement.getAttribute('name')}-list`;
67
+ datalistElement.setAttribute('id', listID);
68
+ inputElement === null || inputElement === void 0 ? void 0 : inputElement.setAttribute('data-list', listID);
69
+ this.appendChild(datalistElement);
70
+ }
71
+ datalistElement.setAttribute('slot', 'datalist');
72
+ datalistElement.querySelectorAll('option').forEach((option) => {
73
+ option.setAttribute('tabindex', '0');
74
+ if (option.textContent == '' && option.hasAttribute('value')) {
75
+ option.textContent = option.getAttribute('value');
56
76
  }
57
- // Clone original input field, re-name and use for display purposes
58
- const displayInputField = inputField.cloneNode();
59
- displayInputField.setAttribute('name', `${inputField.getAttribute('name')}Alt`);
60
- inputField.removeAttribute('data-change-events');
61
- displayInputField.removeAttribute('id');
62
- inputField.after(displayInputField);
63
- // Hide original input field
64
- inputField.setAttribute('type', 'hidden');
65
- // if data list does not exist then create one and append
66
- if (!datalist) {
67
- datalist = document.createElement('datalist');
68
- const listID = safeID('list');
69
- datalist.setAttribute('id', listID);
70
- searchWrapper.appendChild(datalist);
71
- displayInputField.setAttribute('list', listID);
77
+ });
78
+ datalistElement.addEventListener('click', (event) => {
79
+ const optionElement = getOptionFromEvent(event);
80
+ if (optionElement) {
81
+ event.stopPropagation();
82
+ event.preventDefault();
83
+ if (document.activeElement instanceof HTMLElement)
84
+ document.activeElement.blur();
85
+ this.classList.remove('js-show-datalist');
86
+ datalistSelectOption(this, inputElement, optionElement);
72
87
  }
73
- displayInputField.addEventListener('change', function (e) {
74
- inputField.value = displayInputField.value;
75
- });
76
- advancedSelect(this, displayInputField, datalist, false);
77
- const checkMatch = () => {
78
- const match = datalist.querySelector(`option[value="${displayInputField.value}" i]`);
79
- const subMatch = datalist.querySelector(`option[value*="${displayInputField.value}" i]`);
80
- if (match) {
81
- inputField.value = match.getAttribute('data-actual-value');
82
- displayInputField.value = match.getAttribute('data-actual-value');
83
- displayInputField.classList.remove('is-invalid');
84
- displayInputField.closest('label').removeAttribute('data-error');
85
- }
86
- else if (displayInputField.value.length >= minLength && !subMatch) {
87
- displayInputField.classList.add('is-invalid');
88
- displayInputField.closest('label').setAttribute('data-error', 'No results returned');
89
- if (searchWrapper.hasAttribute('data-url'))
90
- datalist.innerHTML = '';
88
+ });
89
+ // #endregion
90
+ // #region control input field
91
+ inputElement.addEventListener('input', () => {
92
+ if (inputElement.value.length >= 1) {
93
+ this.classList.add('has-value');
94
+ }
95
+ else {
96
+ this.classList.remove('has-value');
97
+ }
98
+ if (inputElement.value.length >= minLength) {
99
+ //inputElement.removeAttribute('data-value');
100
+ this.classList.add('js-show-datalist');
101
+ if (this.hasAttribute('data-url')) {
102
+ void search(this, datalistElement, inputElement.value);
91
103
  }
92
104
  else {
93
- displayInputField.classList.remove('is-invalid');
94
- displayInputField.closest('label').removeAttribute('data-error');
95
- }
96
- };
97
- const search = (searchterm) => __awaiter(this, void 0, void 0, function* () {
98
- if (!this.getAttribute('data-url'))
99
- return false;
100
- let ajaxURL = this.getAttribute('data-url');
101
- ajaxURL += `${encodeURI(searchterm)}`;
102
- // Setup controller vars if not already set
103
- if (!window.controller)
104
- window.controller = [];
105
- // Abort if controller already present for this url
106
- if (window.controller[ajaxURL])
107
- window.controller[ajaxURL].abort();
108
- // Create a new controller so it can be aborted if new fetch made
109
- window.controller[ajaxURL] = new AbortController();
110
- const { signal } = controller[ajaxURL];
111
- try {
112
- yield fetch(ajaxURL, {
113
- signal: signal,
114
- method: 'get',
115
- credentials: 'same-origin',
116
- mode: 'no-cors',
117
- headers: new Headers({
118
- 'Content-Type': 'application/json',
119
- Accept: 'application/json',
120
- 'X-Requested-With': 'XMLHttpRequest',
121
- 'X-XSRF-TOKEN': Cookies.get('XSRF-TOKEN'),
122
- }),
123
- })
124
- .then((response) => response.json())
125
- .then((response) => {
126
- // populate datalist
127
- let listString = '';
128
- const loopValues = resolvePath(response, loopSchema, '');
129
- if (isTraversable(loopValues) && typeof loopValues.forEach == 'function') {
130
- loopValues.forEach((item) => {
131
- const actualValue = resolvePath(item, valueSchema, '');
132
- const displayValue = resolvePath(item, displaySchema, '').replace('\n', ', ');
133
- if (!datalist.querySelector(`option[data-actual-value="${actualValue}"]`))
134
- listString += `<option value="${displayValue}" data-actual-value="${actualValue}">${displayValue}</option>`;
135
- });
136
- }
137
- else if (typeof loopValues == 'object') {
138
- for (const [key, value] of Object.entries(loopValues)) {
139
- if (isTraversable(value) && typeof value.forEach == 'function') {
140
- value.forEach((item) => {
141
- const actualValue = resolvePath(item, valueSchema, '');
142
- const displayValue = resolvePath(item, displaySchema, '').replace('\n', ', ');
143
- if (!datalist.querySelector(`option[data-actual-value="${actualValue}"]`))
144
- listString += `<option value="${key}: ${displayValue}" data-actual-value='${actualValue}'>${key}: ${displayValue}</option>`;
145
- });
146
- }
147
- }
148
- }
149
- datalist.innerHTML += listString;
150
- // filter the list on the client side just in case
151
- const text = searchterm.toUpperCase();
152
- for (const option of datalist.options) {
153
- if (option.value.toUpperCase().indexOf(text) > -1) {
154
- option.style.display = 'block';
155
- option.classList.remove('hide');
156
- }
157
- else {
158
- option.style.display = 'none';
159
- option.classList.add('hide');
160
- }
161
- }
162
- searchWrapper.classList.add('was-validated');
163
- checkMatch();
164
- return response;
165
- });
105
+ filterDatalist(datalistElement, inputElement.value);
166
106
  }
167
- catch (error) {
168
- console.log(error);
169
- }
170
- });
171
- datalist.addEventListener('click', function (event) {
172
- if (event && event.target instanceof HTMLElement && event.target.closest('option')) {
173
- const option = event.target.closest('option');
174
- const value = (option === null || option === void 0 ? void 0 : option.hasAttribute('data-actual-value')) ? option === null || option === void 0 ? void 0 : option.getAttribute('data-actual-value') : option === null || option === void 0 ? void 0 : option.getAttribute('data-value');
175
- inputField.value = value;
176
- const changeEvent = new CustomEvent('value-change', {
177
- detail: { value: value },
178
- });
179
- searchWrapper.dispatchEvent(changeEvent);
180
- }
181
- });
182
- this.addEventListener('close-button-pressed', function (event) {
183
- if (searchWrapper.hasAttribute('data-url')) {
184
- datalist.innerHTML = '';
185
- }
186
- inputField === null || inputField === void 0 ? void 0 : inputField.value = '';
187
- searchWrapper.classList.remove('was-validated');
188
- displayInputField.classList.remove('is-invalid');
189
- displayInputField.closest('label').removeAttribute('data-error');
190
- });
191
- // Search the endpoint when 3 characters has been added
192
- if (searchWrapper.hasAttribute('data-url')) {
193
- displayInputField.addEventListener('input', () => {
194
- if (displayInputField.value.length < minLength) {
195
- datalist.innerHTML = '';
196
- }
197
- if (displayInputField.value.length == minLength) {
198
- search(displayInputField.value);
199
- }
200
- });
201
107
  }
202
108
  else {
203
- // on change update oringinal field with the actual value and use displayed input for the nice display text
204
- displayInputField.addEventListener('input', () => {
205
- checkMatch();
206
- });
109
+ this.classList.remove('js-show-datalist');
110
+ }
111
+ });
112
+ inputElement.addEventListener('focus', () => {
113
+ if (inputElement.value == inputElement.getAttribute('data-value')) {
114
+ const selectedValue = inputElement.getAttribute('data-value') || '';
115
+ inputElement.value = '';
116
+ inputElement.setAttribute('placeholder', selectedValue);
117
+ this.classList.remove('js-show-datalist');
118
+ }
119
+ else if (inputElement.value.length >= minLength) {
120
+ this.classList.add('js-show-datalist');
207
121
  }
208
- if (searchWrapper.hasAttribute('data-prevent-submit')) {
209
- const form = searchWrapper.closest('form');
210
- form.addEventListener('submit', (e) => {
211
- e.preventDefault();
212
- });
122
+ });
123
+ inputElement.addEventListener('blur', () => {
124
+ const selectedValue = inputElement.getAttribute('data-value');
125
+ if (!inputElement.value && selectedValue) {
126
+ inputElement.value = selectedValue;
127
+ //inputElement.setAttribute('placeholder', inputElement.getAttribute('data-value'));
128
+ //this.classList.remove('js-show-datalist');
129
+ }
130
+ // Set timeout to allow click event to fire on options before hiding the list again
131
+ setTimeout(() => {
132
+ this.classList.remove('js-force-show-datalist');
133
+ this.classList.remove('js-show-datalist');
134
+ }, 200);
135
+ const placeholder = inputElement.getAttribute('data-placeholder');
136
+ if (placeholder)
137
+ inputElement.setAttribute('placeholder', placeholder);
138
+ });
139
+ // #endregion
140
+ // #region control suffix button
141
+ suffixElement.addEventListener('click', () => {
142
+ const form = this.closest('form');
143
+ if (form && !this.hasAttribute('data-prevent-submit')) {
144
+ form.requestSubmit();
213
145
  }
146
+ else {
147
+ inputElement.focus();
148
+ this.classList.add('js-force-show-datalist');
149
+ }
150
+ });
151
+ // #endregion
152
+ // #region keyboard navigation
153
+ this.addEventListener('keydown', (event) => {
154
+ var _a;
155
+ switch (event.key) {
156
+ case 'ArrowDown':
157
+ //event.stopPropagation();
158
+ //event.preventDefault();
159
+ if (event && event.target instanceof HTMLElement && event.target == inputElement) {
160
+ (_a = this.querySelector('datalist option:not(.js-hide)')) === null || _a === void 0 ? void 0 : _a.focus();
161
+ }
162
+ break;
163
+ }
164
+ /*
165
+ if (event && event.target instanceof HTMLElement && event.target.closest('a, button, summary')) {
166
+ const activeItem = document.activeElement;
167
+ const prevIndex = Array.from(topLevelmenuItems).indexOf(activeItem) - 1;
168
+ const nextIndex = Array.from(topLevelmenuItems).indexOf(activeItem) + 1;
169
+
170
+ switch (
171
+ event.keyCode // change to event.key to key to use the above variable
172
+ ) {
173
+ case 27: // Esc
174
+ if (activeItem.closest('details')) {
175
+ event.stopPropagation();
176
+ event.preventDefault();
177
+ activeItem.closest('details').removeAttribute('open');
178
+ activeItem.closest('details').querySelector(':scope summary').focus();
179
+ } else {
180
+ event.stopPropagation();
181
+ menuButton.focus();
182
+ }
183
+
184
+ break;
185
+ case 32: // Space
186
+ case 13: // Enter
187
+ break;
188
+ case 35: // end
189
+ event.stopPropagation();
190
+ event.preventDefault();
191
+
192
+ this.querySelector('details[open]').removeAttribute('open');
193
+ Array.from(menuItems)[menuItems.length - 1].focus();
194
+
195
+ break;
196
+ case 36: // home
197
+ event.stopPropagation();
198
+ event.preventDefault();
199
+
200
+ this.querySelector('details[open]').removeAttribute('open');
201
+ Array.from(menuItems)[0].focus();
202
+
203
+ break;
204
+ case 38: // up
205
+ event.stopPropagation();
206
+ event.preventDefault();
207
+
208
+ if (Array.from(topLevelmenuItems).indexOf(activeItem) > -1) {
209
+ if (Array.from(topLevelmenuItems)[prevIndex] != undefined)
210
+ Array.from(topLevelmenuItems)[prevIndex].focus();
211
+ else Array.from(topLevelmenuItems)[topLevelmenuItems.length - 1].focus();
212
+ } else if (activeItem.closest('details')) {
213
+ const subMenuItems = activeItem
214
+ .closest('details')
215
+ .querySelectorAll('a, button, :scope details > summary');
216
+ subPrevIndex = Array.from(subMenuItems).indexOf(activeItem) - 1;
217
+
218
+ if (Array.from(subMenuItems)[subPrevIndex] != undefined) Array.from(subMenuItems)[subPrevIndex].focus();
219
+ else Array.from(subMenuItems)[subMenuItems.length - 1].focus();
220
+ }
221
+
222
+ break;
223
+ case 40: // down
224
+ event.stopPropagation();
225
+ event.preventDefault();
226
+
227
+ if (Array.from(topLevelmenuItems).indexOf(activeItem) > -1) {
228
+ if (Array.from(topLevelmenuItems)[nextIndex] != undefined)
229
+ Array.from(topLevelmenuItems)[nextIndex].focus();
230
+ else Array.from(topLevelmenuItems)[0].focus();
231
+ } else if (activeItem.closest('details')) {
232
+ const subMenuItems = activeItem
233
+ .closest('details')
234
+ .querySelectorAll('a, button, :scope details > summary');
235
+ subNextIndex = Array.from(subMenuItems).indexOf(activeItem) + 1;
236
+
237
+ if (Array.from(subMenuItems)[subNextIndex] != undefined) Array.from(subMenuItems)[subNextIndex].focus();
238
+ else Array.from(subMenuItems)[0].focus();
239
+ }
240
+
241
+ break;
242
+ }
243
+ }
244
+
245
+ */
246
+ });
247
+ // #endregion
248
+ // #region empty button
249
+ clearBtn === null || clearBtn === void 0 ? void 0 : clearBtn.addEventListener('click', () => {
250
+ this.classList.remove('js-show-datalist');
251
+ inputElement.value = '';
252
+ inputElement.removeAttribute('data-value');
253
+ inputElement.focus();
254
+ this.classList.remove('has-value');
255
+ inputElement.setAttribute('placeholder', this.getAttribute('data-original-placeholder') || '');
256
+ const inputName = inputElement.getAttribute('name');
257
+ const alternateInput = inputName ? this.querySelector(`[name="${inputName}Alt"]`) : null;
258
+ alternateInput === null || alternateInput === void 0 ? void 0 : alternateInput.remove();
259
+ datalistElement.querySelectorAll('option').forEach((option) => {
260
+ option.classList.remove('active');
261
+ });
214
262
  });
215
263
  }
216
264
  }