@iamproperty/components 7.5.1--beta5 → 7.5.1--beta7

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 (196) 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/applied-filters.css +1 -1
  6. package/assets/css/components/applied-filters.css.map +1 -1
  7. package/assets/css/components/calendar.component.css +1 -1
  8. package/assets/css/components/calendar.component.css.map +1 -1
  9. package/assets/css/components/card.component.css +1 -1
  10. package/assets/css/components/card.component.css.map +1 -1
  11. package/assets/css/components/fileupload.css +1 -1
  12. package/assets/css/components/fileupload.css.map +1 -1
  13. package/assets/css/components/input-range.component.css +1 -0
  14. package/assets/css/components/input-range.component.css.map +1 -0
  15. package/assets/css/components/input.component.css +1 -0
  16. package/assets/css/components/input.component.css.map +1 -0
  17. package/assets/css/components/modal.component.css +1 -0
  18. package/assets/css/components/modal.component.css.map +1 -0
  19. package/assets/css/components/multi-step-modal.component.css +1 -0
  20. package/assets/css/components/multi-step-modal.component.css.map +1 -0
  21. package/assets/css/components/multi-step-modal.global.css +1 -0
  22. package/assets/css/components/multi-step-modal.global.css.map +1 -0
  23. package/assets/css/components/multiselect.css +1 -1
  24. package/assets/css/components/multiselect.css.map +1 -1
  25. package/assets/css/components/nav.component.css +1 -1
  26. package/assets/css/components/nav.component.css.map +1 -1
  27. package/assets/css/components/pagination.css +1 -1
  28. package/assets/css/components/pagination.css.map +1 -1
  29. package/assets/css/components/password.component.css +1 -0
  30. package/assets/css/components/password.component.css.map +1 -0
  31. package/assets/css/components/slider.css +1 -1
  32. package/assets/css/components/slider.css.map +1 -1
  33. package/assets/css/components/tabs.component.css +1 -1
  34. package/assets/css/components/tabs.component.css.map +1 -1
  35. package/assets/css/components/tabs.config.css +1 -1
  36. package/assets/css/components/tabs.config.css.map +1 -1
  37. package/assets/css/core.min.css +1 -1
  38. package/assets/css/core.min.css.map +1 -1
  39. package/assets/css/mobile-core.min.css +1 -1
  40. package/assets/css/mobile-core.min.css.map +1 -1
  41. package/assets/css/mobile.min.css +1 -1
  42. package/assets/css/mobile.min.css.map +1 -1
  43. package/assets/css/style.min.css +1 -1
  44. package/assets/css/style.min.css.map +1 -1
  45. package/assets/js/components/accordion/accordion.component.js +1 -1
  46. package/assets/js/components/accordion/accordion.component.min.js +3 -3
  47. package/assets/js/components/accordion/accordion.component.min.js.map +1 -1
  48. package/assets/js/components/actionbar/actionbar.component.js +2 -4
  49. package/assets/js/components/actionbar/actionbar.component.min.js +4 -4
  50. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
  51. package/assets/js/components/address-lookup/address-lookup.component.js +45 -0
  52. package/assets/js/components/address-lookup/address-lookup.component.min.js +12 -4
  53. package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
  54. package/assets/js/components/advanced-select/advanced-select.component.min.js +1 -1
  55. package/assets/js/components/applied-filters/applied-filters.component.js +0 -2
  56. package/assets/js/components/applied-filters/applied-filters.component.min.js +5 -7
  57. package/assets/js/components/applied-filters/applied-filters.component.min.js.map +1 -1
  58. package/assets/js/components/barchart/barchart.component.min.js +1 -1
  59. package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
  60. package/assets/js/components/calendar/calendar.component.min.js +5 -5
  61. package/assets/js/components/card/card.component.min.js +8 -8
  62. package/assets/js/components/card/card.component.min.js.map +1 -1
  63. package/assets/js/components/carousel/carousel.component.min.js +1 -1
  64. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  65. package/assets/js/components/content/content.component.min.js +1 -1
  66. package/assets/js/components/darkmode/darkmode.component.min.js +1 -1
  67. package/assets/js/components/doughnutchart/doughnutchart.component.min.js +1 -1
  68. package/assets/js/components/fileupload/fileupload.component.min.js +4 -4
  69. package/assets/js/components/filter-card/filter-card.component.js +19 -0
  70. package/assets/js/components/filter-card/filter-card.component.min.js +4 -4
  71. package/assets/js/components/filter-card/filter-card.component.min.js.map +1 -1
  72. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  73. package/assets/js/components/header/header.component.min.js +1 -1
  74. package/assets/js/components/inline-edit/inline-edit.component.min.js +1 -1
  75. package/assets/js/components/input/input.component.js +128 -0
  76. package/assets/js/components/input/input.component.min.js +16 -0
  77. package/assets/js/components/input/input.component.min.js.map +1 -0
  78. package/assets/js/components/input-range/input-range.component.js +62 -0
  79. package/assets/js/components/input-range/input-range.component.min.js +14 -0
  80. package/assets/js/components/input-range/input-range.component.min.js.map +1 -0
  81. package/assets/js/components/marketing/marketing.component.min.js +1 -1
  82. package/assets/js/components/menu/menu.component.min.js +1 -1
  83. package/assets/js/components/milestone/milestone.component.min.js +1 -1
  84. package/assets/js/components/milestone-group/milestone-group.component.min.js +1 -1
  85. package/assets/js/components/modal/modal.component.js +141 -0
  86. package/assets/js/components/modal/modal.component.min.js +28 -0
  87. package/assets/js/components/modal/modal.component.min.js.map +1 -0
  88. package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
  89. package/assets/js/components/multi-step-modal/multi-step-modal.component.js +233 -0
  90. package/assets/js/components/multi-step-modal/multi-step-modal.component.min.js +17 -0
  91. package/assets/js/components/multi-step-modal/multi-step-modal.component.min.js.map +1 -0
  92. package/assets/js/components/multiselect/multiselect.component.js +1 -1
  93. package/assets/js/components/multiselect/multiselect.component.min.js +5 -5
  94. package/assets/js/components/multiselect/multiselect.component.min.js.map +1 -1
  95. package/assets/js/components/nav/nav.component.min.js +5 -5
  96. package/assets/js/components/nav/nav.component.min.js.map +1 -1
  97. package/assets/js/components/notification/notification.component.min.js +1 -1
  98. package/assets/js/components/pagination/pagination.component.min.js +3 -3
  99. package/assets/js/components/password/password.component.js +93 -0
  100. package/assets/js/components/password/password.component.min.js +17 -0
  101. package/assets/js/components/password/password.component.min.js.map +1 -0
  102. package/assets/js/components/rank/rank.component.min.js +1 -1
  103. package/assets/js/components/rankings/rankings.component.min.js +1 -1
  104. package/assets/js/components/record-card/record-card.component.min.js +4 -4
  105. package/assets/js/components/record-card/record-card.component.min.js.map +1 -1
  106. package/assets/js/components/search/search.component.js +1 -1
  107. package/assets/js/components/search/search.component.min.js +5 -5
  108. package/assets/js/components/search/search.component.min.js.map +1 -1
  109. package/assets/js/components/slider/slider.component.min.js +3 -3
  110. package/assets/js/components/split-button/split-button.component.min.js +1 -1
  111. package/assets/js/components/std-address-lookup/std-address-lookup.component.js +5 -1
  112. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js +22 -9
  113. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js.map +1 -1
  114. package/assets/js/components/table/table.component.min.js +3 -3
  115. package/assets/js/components/table/table.component.min.js.map +1 -1
  116. package/assets/js/components/table-ajax/table-ajax.component.min.js +4 -4
  117. package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -1
  118. package/assets/js/components/table-basic/table-basic.component.min.js +1 -1
  119. package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -1
  120. package/assets/js/components/table-no-submit/table-no-submit.component.min.js +1 -1
  121. package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -1
  122. package/assets/js/components/table-submit/table-submit.component.min.js +1 -1
  123. package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -1
  124. package/assets/js/components/tabs/tabs.component.min.js +2 -2
  125. package/assets/js/components/video-card/video-card.component.min.js +4 -4
  126. package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
  127. package/assets/js/components/word-count/word-count.component.min.js +1 -1
  128. package/assets/js/modules/applied-filters.js +78 -61
  129. package/assets/js/modules/card.module.js +6 -1
  130. package/assets/js/modules/dialogs.js +6 -2
  131. package/assets/js/modules/password.js +72 -0
  132. package/assets/js/modules/table.js +10 -6
  133. package/assets/js/scripts.bundle.js +2 -3
  134. package/assets/js/scripts.bundle.js.map +1 -1
  135. package/assets/js/scripts.bundle.min.js +2 -2
  136. package/assets/js/scripts.bundle.min.js.map +1 -1
  137. package/assets/js/scripts.js +0 -2
  138. package/assets/js/tests/helpers.spec.js +54 -1
  139. package/assets/sass/_components.scss +2 -0
  140. package/assets/sass/_elements.scss +2 -0
  141. package/assets/sass/components/actionbar.component.scss +1 -0
  142. package/assets/sass/components/address-lookup.component.scss +24 -0
  143. package/assets/sass/components/applied-filters.scss +10 -14
  144. package/assets/sass/components/input-range.component.scss +38 -0
  145. package/assets/sass/components/input.component.scss +102 -0
  146. package/assets/sass/components/modal.component.scss +269 -0
  147. package/assets/sass/components/multi-step-modal.component.scss +255 -0
  148. package/assets/sass/components/multi-step-modal.global.scss +92 -0
  149. package/assets/sass/components/multiselect.scss +2 -2
  150. package/assets/sass/components/password.component.scss +60 -0
  151. package/assets/sass/components/tabs.config.scss +2 -2
  152. package/assets/sass/elements/badge-tag.scss +0 -1
  153. package/assets/sass/elements/details.scss +12 -7
  154. package/assets/sass/elements/dialog.scss +46 -5
  155. package/assets/sass/elements/forms.scss +41 -177
  156. package/assets/sass/elements/hr.scss +1 -1
  157. package/assets/sass/elements/modal.scss +19 -21
  158. package/assets/sass/elements/prefix.scss +115 -0
  159. package/assets/ts/components/accordion/accordion.component.ts +1 -1
  160. package/assets/ts/components/actionbar/actionbar.component.ts +3 -10
  161. package/assets/ts/components/address-lookup/address-lookup.component.ts +60 -0
  162. package/assets/ts/components/applied-filters/applied-filters.component.ts +0 -2
  163. package/assets/ts/components/filter-card/filter-card.component.ts +27 -0
  164. package/assets/ts/components/input/input.component.ts +168 -0
  165. package/assets/ts/components/input-range/input-range.component.ts +78 -0
  166. package/assets/ts/components/modal/modal.component.ts +188 -0
  167. package/assets/ts/components/multi-step-modal/multi-step-modal.component.ts +304 -0
  168. package/assets/ts/components/multiselect/multiselect.component.ts +1 -1
  169. package/assets/ts/components/password/password.component.ts +118 -0
  170. package/assets/ts/components/search/search.component.ts +1 -1
  171. package/assets/ts/components/std-address-lookup/std-address-lookup.component.ts +5 -3
  172. package/assets/ts/modules/applied-filters.ts +107 -71
  173. package/assets/ts/modules/card.module.ts +9 -4
  174. package/assets/ts/modules/dialogs.ts +6 -2
  175. package/assets/ts/modules/password.ts +82 -0
  176. package/assets/ts/modules/table.ts +13 -6
  177. package/assets/ts/scripts.ts +2 -2
  178. package/assets/ts/tests/helpers.spec.ts +100 -1
  179. package/dist/components.es.js +641 -959
  180. package/dist/components.umd.js +281 -182
  181. package/package.json +2 -2
  182. package/src/components/Input/Input.vue +19 -363
  183. package/src/components/InputRange/InputRange.vue +22 -0
  184. package/src/components/Modal/Modal.vue +22 -0
  185. package/src/components/MultiStepModal/MultiStepModal.vue +23 -0
  186. package/src/components/{PasswordIndicator/PasswordIndicator.vue → Password/Password.vue} +23 -23
  187. package/assets/js/components/password-indicator/password-indicator.component.js +0 -19
  188. package/assets/js/components/password-indicator/password-indicator.component.min.js +0 -7
  189. package/assets/js/components/password-indicator/password-indicator.component.min.js.map +0 -1
  190. package/assets/js/modules/form.js +0 -125
  191. package/assets/js/modules/inputs.js +0 -151
  192. package/assets/js/modules/password-indicator.js +0 -21
  193. package/assets/ts/components/password-indicator/password-indicator.component.ts +0 -24
  194. package/assets/ts/modules/form.ts +0 -166
  195. package/assets/ts/modules/inputs.ts +0 -181
  196. package/assets/ts/modules/password-indicator.ts +0 -29
@@ -0,0 +1,188 @@
1
+ import { trackComponent, trackComponentRegistered } from '../_global';
2
+ import { cardHTML, setupCard } from '../../modules/card.module';
3
+ import iamMenu from '../menu/menu.component';
4
+ import Modal from '../../../../src/components/Modal/Modal.vue';
5
+
6
+ trackComponentRegistered('iam-card');
7
+
8
+ class iamModal extends HTMLElement {
9
+ constructor() {
10
+ super();
11
+ this.attachShadow({ mode: 'open' });
12
+
13
+ const assetLocation = document.body.hasAttribute('data-assets-location')
14
+ ? document.body.getAttribute('data-assets-location')
15
+ : '/assets';
16
+ const loadCSS = `@import "${assetLocation}/css/components/modal.component.css";`;
17
+
18
+ const template = document.createElement('template');
19
+ template.innerHTML = `
20
+ <style>
21
+ ${this.hasAttribute('css') ? `@import "${this.getAttribute('css')}";` : ``}
22
+
23
+ ${loadCSS}
24
+ </style>
25
+ <link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous" />
26
+ <dialog>
27
+ <button class="btn btn-compact btn-secondary fa-xmark-large" data-close>Close</button>
28
+ <div class="scroll">
29
+ <i class="fa-light fa-circle" aria-hidden="true">
30
+ <i class="fa-regular fa-${this.hasAttribute('data-icon') ? this.getAttribute('data-icon') : 'info'}" aria-hidden="true"></i>
31
+ </i>
32
+ <slot></slot>
33
+ <div class="btn-group">
34
+ <button class="btn btn-secondary" data-cancel>Cancel</button>
35
+ <slot name="agreed-button">
36
+ <button class="btn btn-primary" data-agreed>${this.hasAttribute('data-agreed-text') ? this.getAttribute('data-agreed-text') : 'Ok'}</button>
37
+ </slot>
38
+ </div>
39
+ </div>
40
+ </dialog>
41
+ `;
42
+
43
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
44
+ }
45
+
46
+ connectedCallback(): void {
47
+
48
+ const originalDialog = this.querySelector('dialog');
49
+
50
+ const id = this.hasAttribute('id') ? this.getAttribute('id') : originalDialog?.getAttribute('id');
51
+ const dialog = this.shadowRoot?.querySelector('dialog');
52
+ const closeButton = this.shadowRoot?.querySelector('[data-close]');
53
+ const cancelButton = this.shadowRoot?.querySelector('[data-cancel]');
54
+ const agreedButton = this.shadowRoot?.querySelector('[data-agreed]');
55
+ const slottedAgreedButton = this.querySelector('button[slot="agreed-button"]');
56
+ const modalType = this.hasAttribute('data-type') ? this.getAttribute('data-type') : 'passive';
57
+
58
+
59
+
60
+
61
+ const openModal = () => {
62
+ dialog?.showModal();
63
+ dialog?.focus();
64
+
65
+ const closeEvent = new CustomEvent('modal-opened', {
66
+ bubbles: true,
67
+ cancelable: true,
68
+ detail: { modalId: id },
69
+ });
70
+
71
+ this.dispatchEvent(closeEvent);
72
+
73
+ window.dataLayer = window.dataLayer || [];
74
+ window.dataLayer.push({
75
+ event: 'openModal',
76
+ id: id,
77
+ });
78
+ }
79
+
80
+ document.addEventListener('click', (e) => {
81
+
82
+ if(e.target.matches(`[command="show-modal"][commandfor="${id}"]`) || e.target.matches(`[data-modal="${id}"]`)){
83
+ openModal();
84
+ }
85
+ });
86
+
87
+ // Disable the original event
88
+ originalDialog?.addEventListener('command', (e) => {
89
+
90
+ if (event.command == "show-modal") {
91
+ e.preventDefault();
92
+ }
93
+ });
94
+
95
+ originalDialog?.addEventListener('command', (e) => {
96
+
97
+ if (event.command == "close") {
98
+ closeModal();
99
+ }
100
+ });
101
+
102
+ originalDialog?.addEventListener('close', (e) => {
103
+
104
+ closeModal();
105
+ });
106
+
107
+ // Move the submit button so that the slot functionality works
108
+ Array.from(originalDialog?.querySelectorAll('[slot]')).forEach((element) => {
109
+ this.moveBefore(element, originalDialog);
110
+ });
111
+
112
+ const closeModal = () => {
113
+ dialog?.close();
114
+
115
+ const closeEvent = new CustomEvent('modal-closed', {
116
+ bubbles: true,
117
+ cancelable: true,
118
+ detail: { modalId: id },
119
+ });
120
+
121
+ this.dispatchEvent(closeEvent);
122
+
123
+ window.dataLayer = window.dataLayer || [];
124
+ window.dataLayer.push({
125
+ event: 'closeModal',
126
+ id: id,
127
+ });
128
+ }
129
+
130
+ closeButton?.addEventListener('click', () => {
131
+ closeModal();
132
+ });
133
+
134
+ cancelButton?.addEventListener('click', () => {
135
+ closeModal();
136
+ });
137
+
138
+ agreedButton?.addEventListener('click', () => {
139
+
140
+ const agreedEvent = new CustomEvent('agreed', {
141
+ detail: { modalId: id },
142
+ });
143
+
144
+ this.dispatchEvent(agreedEvent);
145
+
146
+ closeModal();
147
+ });
148
+
149
+ slottedAgreedButton?.addEventListener('click', () => {
150
+
151
+ const agreedEvent = new CustomEvent('agreed', {
152
+ detail: { modalId: id },
153
+ });
154
+
155
+ this.dispatchEvent(agreedEvent);
156
+
157
+ closeModal();
158
+ });
159
+
160
+ this.addEventListener('close-modal', () => {
161
+ closeModal();
162
+ });
163
+
164
+ this.addEventListener('click', (event) => {
165
+
166
+ // Small fix to make sure the dialog isn't a dialog inside of a dialog.
167
+ const style = window.getComputedStyle(dialog);
168
+ if (style.display === 'contents') dialog = dialog.parentNode.closest('dialog[open]');
169
+
170
+ // Dont allow the backdrop to be clicked when transactional
171
+ if (modalType != 'transactional' && modalType != 'acknowledgement') {
172
+ const dialogDimensions = dialog.getBoundingClientRect();
173
+
174
+ if (
175
+ event.clientX < dialogDimensions.left ||
176
+ event.clientX > dialogDimensions.right ||
177
+ event.clientY < dialogDimensions.top ||
178
+ event.clientY > dialogDimensions.bottom
179
+ ) {
180
+ if (!event.target.closest('dialog *'))
181
+ closeModal(); // Weird bug when interacting with radio input fields within dialogs cuases it to close
182
+ }
183
+ }
184
+ });
185
+ }
186
+ }
187
+
188
+ export default iamModal;
@@ -0,0 +1,304 @@
1
+ import { trackComponent, trackComponentRegistered } from '../_global';
2
+
3
+ trackComponentRegistered('iam-multi-step-modal');
4
+
5
+ class iamMultiStepModal extends HTMLElement {
6
+ constructor() {
7
+ super();
8
+ this.attachShadow({ mode: 'open' });
9
+
10
+ const assetLocation = document.body.hasAttribute('data-assets-location')
11
+ ? document.body.getAttribute('data-assets-location')
12
+ : '/assets';
13
+ const loadCSS = `@import "${assetLocation}/css/components/multi-step-modal.component.css";`;
14
+
15
+ const template = document.createElement('template');
16
+ template.innerHTML = `
17
+ <style>
18
+ ${loadCSS}
19
+ </style>
20
+ <link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous" />
21
+ <dialog>
22
+ <button class="btn btn-compact btn-secondary fa-xmark-large" data-close>Close</button>
23
+ <div class="steps" parts="steps">
24
+ </div>
25
+ <slot></slot>
26
+ </dialog>
27
+ `;
28
+
29
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
30
+ }
31
+
32
+ connectedCallback(): void {
33
+
34
+ const originalDialog = this.querySelector('dialog');
35
+
36
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
37
+ const MultiStepComponent = this;
38
+ const id = this.hasAttribute('id') ? this.getAttribute('id') : originalDialog?.getAttribute('id');
39
+ const dialog = this.shadowRoot?.querySelector('dialog');
40
+
41
+ const closeButton = this.shadowRoot?.querySelector('[data-close]');
42
+ const button = document.querySelector(`[data-modal="${id}"]`);
43
+
44
+ const steps = this.shadowRoot.querySelector('.steps');
45
+ const form = this.querySelector('form');
46
+
47
+ const openModal = () => {
48
+ dialog?.showModal();
49
+ dialog?.focus();
50
+
51
+ const closeEvent = new CustomEvent('modal-opened', {
52
+ bubbles: true,
53
+ cancelable: true,
54
+ detail: { modalId: id },
55
+ });
56
+
57
+ this.dispatchEvent(closeEvent);
58
+
59
+ window.dataLayer = window.dataLayer || [];
60
+ window.dataLayer.push({
61
+ event: 'openModal',
62
+ id: id,
63
+ });
64
+ }
65
+
66
+ // Disable the original event
67
+ originalDialog?.addEventListener('command', (e) => {
68
+
69
+ if (event.command == "show-modal") {
70
+ e.preventDefault();
71
+ }
72
+ });
73
+
74
+ document.addEventListener('click', (e) => {
75
+
76
+ if(e.target.matches(`[command="show-modal"][commandfor="${id}"]`) || e.target.matches(`[data-modal="${id}"]`)){
77
+ openModal();
78
+ }
79
+ });
80
+
81
+ button?.addEventListener('click', () => {
82
+ dialog?.showModal();
83
+ dialog?.focus();
84
+
85
+ const closeEvent = new CustomEvent('modal-opened', {
86
+ bubbles: true,
87
+ cancelable: true,
88
+ detail: { modalId: id },
89
+ });
90
+
91
+ this.dispatchEvent(closeEvent);
92
+
93
+ window.dataLayer = window.dataLayer || [];
94
+ window.dataLayer.push({
95
+ event: 'openModal',
96
+ id: id,
97
+ });
98
+ });
99
+
100
+ const closeModal = () => {
101
+ dialog?.close();
102
+
103
+ const closeEvent = new CustomEvent('modal-closed', {
104
+ bubbles: true,
105
+ cancelable: true,
106
+ detail: { modalId: id },
107
+ });
108
+
109
+ this.dispatchEvent(closeEvent);
110
+
111
+ window.dataLayer = window.dataLayer || [];
112
+ window.dataLayer.push({
113
+ event: 'closeModal',
114
+ id: id,
115
+ });
116
+ }
117
+
118
+ closeButton?.addEventListener('click', () => {
119
+ closeModal();
120
+ });
121
+
122
+ const fieldsets = Array.from(MultiStepComponent.querySelectorAll('fieldset[data-title]'));
123
+
124
+ fieldsets.forEach((fieldset, index) => {
125
+ steps.insertAdjacentHTML(
126
+ 'beforeend',
127
+ `<button data-title="${fieldset.getAttribute('data-title')}" type="button" class="${index == 0 ? 'active' : ''}" tabindex="-1">${fieldset.getAttribute('data-title')}</button>`
128
+ );
129
+
130
+ if (index === 0) fieldset.classList.add('active');
131
+
132
+ const btnWrapper = document.createElement('div');
133
+ btnWrapper.classList.add('btn--wrapper');
134
+ fieldset.appendChild(btnWrapper);
135
+
136
+ if (index != 0)
137
+ btnWrapper.innerHTML += `<button data-title="${fieldsets[index - 1].getAttribute('data-title')}" class="btn btn-secondary mb-0" data-previous type="button">Previous</button>`;
138
+
139
+ if (index != fieldsets.length - 1)
140
+ btnWrapper.innerHTML += `<button data-title="${fieldsets[index + 1].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="button">Next</button>`;
141
+
142
+ // Last fieldset
143
+ if (index == fieldsets.length - 1) {
144
+ if (form && form.querySelector(':scope > button[type="submit"]')) {
145
+ const existingButton = form.querySelector(':scope > button[type="submit"]');
146
+ existingButton.classList.add('mb-0');
147
+
148
+ btnWrapper.insertAdjacentElement('beforeend', existingButton);
149
+ } else
150
+ btnWrapper.innerHTML += `<button data-title="${fieldsets[index].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="submit">Submit</button>`;
151
+ }
152
+ });
153
+
154
+ // Open the fieldset with an error inside
155
+ const validatedFieldsets = Array.from(MultiStepComponent.querySelectorAll('fieldset.was-validated'));
156
+ for (let i = 0; i < validatedFieldsets.length; i++) {
157
+ const fieldset = validatedFieldsets[i];
158
+ const fieldsetID = fieldset.getAttribute('data-title');
159
+
160
+ if (fieldset.querySelector('.is-invalid')) {
161
+ Array.from(MultiStepComponent.querySelectorAll(`[data-title="${fieldsetID}"]`)).forEach((element) => {
162
+ element.classList.add('active');
163
+ });
164
+
165
+ break;
166
+ } else {
167
+ Array.from(MultiStepComponent.querySelectorAll(`[data-title="${fieldsetID}"]`)).forEach((element) => {
168
+ element.classList.add('valid');
169
+ });
170
+ }
171
+ }
172
+
173
+ // Prevent the bubble messages
174
+ MultiStepComponent.addEventListener(
175
+ 'invalid',
176
+ (function () {
177
+ return function (e): any {
178
+ e.preventDefault();
179
+ };
180
+ })(),
181
+ true
182
+ );
183
+
184
+ function validateFieldset(button): void {
185
+ const currentFieldset = MultiStepComponent.querySelector(`fieldset.active`)
186
+ ? MultiStepComponent.querySelector(`fieldset.active`)
187
+ : MultiStepComponent.querySelector(`fieldset[data-title]`);
188
+ const currentFieldsetID = currentFieldset.getAttribute('data-title');
189
+ let isFieldsetValid = true;
190
+
191
+ currentFieldset.classList.add('was-validated');
192
+
193
+ Array.from(currentFieldset.querySelectorAll('input')).forEach((input) => {
194
+ if (!input.checkValidity()) isFieldsetValid = false;
195
+ });
196
+
197
+ // If valid mode to next field set
198
+ if (!isFieldsetValid) {
199
+ Array.from(MultiStepComponent.querySelectorAll(`[data-title="${currentFieldsetID}"]`)).forEach((element) => {
200
+ element.classList.remove('valid');
201
+ });
202
+
203
+ Array.from(MultiStepComponent.shadowRoot.querySelectorAll(`[data-title="${currentFieldsetID}"]`)).forEach(
204
+ (element) => {
205
+ element.classList.remove('valid');
206
+ }
207
+ );
208
+ } else {
209
+ Array.from(MultiStepComponent.querySelectorAll(`[data-title="${currentFieldsetID}"]`)).forEach((element) => {
210
+ element.classList.add('valid');
211
+ });
212
+
213
+ Array.from(MultiStepComponent.shadowRoot.querySelectorAll(`[data-title="${currentFieldsetID}"]`)).forEach(
214
+ (element) => {
215
+ element.classList.add('valid');
216
+ }
217
+ );
218
+ }
219
+
220
+ // Allow the previous button to navigate
221
+ if (isFieldsetValid || !button.hasAttribute('data-next')) {
222
+ const fieldset = MultiStepComponent.querySelector(
223
+ `fieldset[data-title="${button.getAttribute('data-title')}"]`
224
+ );
225
+ const step = MultiStepComponent.shadowRoot.querySelector(
226
+ `.steps button[data-title="${button.getAttribute('data-title')}"]`
227
+ );
228
+
229
+ Array.from(MultiStepComponent.querySelectorAll('button')).forEach((button) => {
230
+ button.classList.remove('active');
231
+ });
232
+ Array.from(MultiStepComponent.querySelectorAll('fieldset')).forEach((button) => {
233
+ button.classList.remove('active');
234
+ });
235
+
236
+ step.classList.add('active');
237
+ fieldset.classList.add('active');
238
+ }
239
+
240
+ const fieldsetCount = Array.from(MultiStepComponent.querySelectorAll(`fieldset`)).length;
241
+ const validFieldsetCount = Array.from(MultiStepComponent.querySelectorAll(`fieldset.valid`)).length;
242
+
243
+ // update the progress bar
244
+ MultiStepComponent.style.setProperty('--progress', `${(validFieldsetCount / (fieldsetCount - 1)) * 100}%`);
245
+ }
246
+
247
+ // remove error messages from server
248
+ MultiStepComponent.addEventListener('keydown', (event) => {
249
+ if (event && event.target instanceof HTMLElement && event.target.closest('button')) {
250
+ const button = event.target.closest('button');
251
+
252
+ if (event.keyCode == 13 && button.getAttribute('type') != 'submit') {
253
+ event.preventDefault();
254
+ validateFieldset(button);
255
+ }
256
+ }
257
+
258
+ if (event && event.target instanceof HTMLElement && event.target.closest('input')) {
259
+ const input = event.target.closest('input');
260
+
261
+ input.classList.remove('is-invalid');
262
+
263
+ if (event.keyCode == 13) {
264
+ event.preventDefault();
265
+ }
266
+ }
267
+ });
268
+
269
+ MultiStepComponent.addEventListener('click', (event) => {
270
+ if (event && event.target instanceof HTMLElement && event.target.closest('button[type="submit"]')) {
271
+ const form = event.target.closest('form');
272
+ form.classList.add('was-validated');
273
+ }
274
+ return null;
275
+ });
276
+
277
+ MultiStepComponent.shadowRoot.addEventListener('click', (event) => {
278
+ if (event && event.target instanceof HTMLElement && event.target.closest('button[data-title]')) {
279
+ const button = event.target.closest('button[data-title]');
280
+
281
+ validateFieldset(button);
282
+ }
283
+ return null;
284
+ });
285
+
286
+ trackComponent(MultiStepComponent, 'iam-multi-step', []);
287
+ }
288
+
289
+ static get observedAttributes(): any {
290
+ return ['data-image'];
291
+ }
292
+
293
+ attributeChangedCallback(attrName, oldVal, newVal): void {
294
+ switch (attrName) {
295
+ case 'data-total': {
296
+ if (this.shadowRoot.querySelector('.card__total'))
297
+ this.shadowRoot.querySelector('.card__total').innerHTML = newVal;
298
+ break;
299
+ }
300
+ }
301
+ }
302
+ }
303
+
304
+ export default iamMultiStepModal;
@@ -35,7 +35,7 @@ class iamMultiselect extends HTMLElement {
35
35
  <div class="admin-panel dropdown" part="dropdown">
36
36
  <slot></slot>
37
37
  </div>
38
- <button id="clear"><span class="visually-hidden">Clear</span></button>
38
+ <button id="clear" class="btn btn-action "><span class="visually-hidden">Clear</span></button>
39
39
  </div>
40
40
  </div>
41
41
  </label>
@@ -0,0 +1,118 @@
1
+ import { trackComponentRegistered } from '../_global';
2
+ import hibpCheck from '../../vendor/hibp.js';
3
+
4
+ trackComponentRegistered('iam-password');
5
+
6
+ class iamPassword extends HTMLElement {
7
+ constructor() {
8
+ super();
9
+ this.attachShadow({ mode: 'open' });
10
+
11
+ const assetLocation = document.body.hasAttribute('data-assets-location')
12
+ ? document.body.getAttribute('data-assets-location')
13
+ : '/assets';
14
+
15
+ const loadCSS = `@import "${assetLocation}/css/components/password.component.css";`;
16
+
17
+
18
+ const template = document.createElement('template');
19
+ template.innerHTML = `
20
+ <style>
21
+ ${loadCSS}
22
+ </style>
23
+ <link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous">
24
+ <div class="wrapper">
25
+ <slot></slot>
26
+ <button type="button" class="suffix fa-solid fa-eye-slash" data-alt-class="suffix fa-solid fa-eye" aria-hidden="true"><span class="visually-hidden">Show password</span></button>
27
+ </div>
28
+ <span class="pwd-checker"></span>
29
+ `;
30
+ this.shadowRoot?.appendChild(template.content.cloneNode(true));
31
+ }
32
+
33
+ connectedCallback(): void {
34
+
35
+
36
+ const input = this.querySelector('input');
37
+
38
+ const buttonEle = this.shadowRoot.querySelector('button')
39
+ const pwdChecker = this.shadowRoot?.querySelector('.pwd-checker')
40
+
41
+ // Switch icon and input type
42
+ buttonEle.addEventListener('click', (event) => {
43
+ const currentType = input.type;
44
+
45
+ const newType = currentType === 'password' ? 'text' : 'password';
46
+ const isPasswordType = currentType === 'password';
47
+
48
+ input.setAttribute('type', newType);
49
+ input.setAttribute('data-password-type', isPasswordType);
50
+
51
+ if (buttonEle.hasAttribute('data-alt-class')) {
52
+ const newClass = buttonEle.getAttribute('data-alt-class');
53
+ buttonEle.setAttribute('data-alt-class', buttonEle.getAttribute('class'));
54
+ buttonEle.setAttribute('class', newClass);
55
+ }
56
+ });
57
+
58
+
59
+
60
+ input.addEventListener('input', (event) => {
61
+
62
+
63
+ const password = input.value;
64
+ const minChars = input.hasAttribute('minlength') ? input.getAttribute('minlength') : 12;
65
+
66
+ let strength = 1;
67
+ const strengthName = ['Very weak', 'Weak', 'Average', 'Strong', 'Very strong'];
68
+ let extraMsg = '';
69
+
70
+ //has number
71
+ if (password.match(/(?=.*[0-9])/)) strength += 1;
72
+ // has special character
73
+ if (password.match(/(?=.*[!,%,&,#,$,^,*,?,_,~,<,>,])/)) strength += 1;
74
+ // has lowercase alpha
75
+ if (password.match(/(?=.*[a-z])/)) strength += 1;
76
+ // has uppercase alpha
77
+ if (password.match(/(?=.*[A-Z])/)) strength += 1;
78
+
79
+ if (password.length < minChars) {
80
+ strength = 1;
81
+ extraMsg = `(must be at least ${minChars} characters.)`;
82
+ }
83
+
84
+ // if the strength is above weak and above the minimum length do some kind of api call to check if its in a list of passwords
85
+
86
+ if (strength >= 3) {
87
+ hibpCheck(password, input);
88
+
89
+ input.addEventListener('hibpCheck', function (event) {
90
+ checkhibpCheck(event, input);
91
+ });
92
+
93
+ function checkhibpCheck(event, input): void {
94
+ console.log(event.detail);
95
+ if (event.detail) {
96
+ // found
97
+ strength = 3;
98
+ extraMsg = `(this password is very common)`;
99
+
100
+ pwdChecker.innerHTML = `Password strength: ${strengthName[strength - 1]} ${extraMsg}`;
101
+ }
102
+
103
+ input.removeEventListener('hibpCheck', checkhibpCheck); // Succeeds
104
+ }
105
+ }
106
+
107
+ if (strength <= 3) pwdChecker.classList.add('invalid-feedback');
108
+ else pwdChecker.classList.remove('invalid-feedback');
109
+
110
+ pwdChecker.setAttribute('data-strength', strength);
111
+ pwdChecker.innerHTML = `Password strength: ${strengthName[strength - 1]} ${extraMsg}`;
112
+
113
+ });
114
+
115
+ }
116
+ }
117
+
118
+ export default iamPassword;
@@ -1,4 +1,4 @@
1
- import Cookies from 'js-cookie';
1
+ import Cookies from '../../../../node_modules/js-cookie/dist/js.cookie.mjs';
2
2
  import { safeID, resolvePath, isTraversable } from '../../modules/helpers';
3
3
  import advancedSelect from '../../modules/advanced-select';
4
4
 
@@ -1554,6 +1554,8 @@ class iamSTDAddressLookup extends HTMLElement {
1554
1554
  data-url="/standardaddress.json?search_query="
1555
1555
  data-postcode="true"
1556
1556
  data-min-chars="5"
1557
+ data-title="Find an address by postcode"
1558
+ data-placeholder="UK, Isle of Man, & Channel Islands "
1557
1559
  ${this.hasAttribute('data-manual') ? 'data-manual' : ''}
1558
1560
  ${this.hasAttribute('data-allow-manual') ? 'data-allow-manual' : ''}
1559
1561
  ${this.hasAttribute('data-use') ? `data-use='${this.getAttribute('data-use')}'` : ''}
@@ -1564,6 +1566,8 @@ class iamSTDAddressLookup extends HTMLElement {
1564
1566
  ${this.hasAttribute('data-error-msg') ? `data-error-msg='${this.getAttribute('data-error-msg')}'` : ''}
1565
1567
  ${this.hasAttribute('data-use-default') ? `data-use-default` : ''}
1566
1568
  ${this.hasAttribute('data-force-manual') ? `data-force-manual` : ''}
1569
+ ${this.hasAttribute('data-matched') ? `data-matched='${this.getAttribute('data-matched')}'` : ''}
1570
+ ${this.hasAttribute('data-matched-label') ? `data-matched-label='${this.getAttribute('data-matched-label')}'` : ''}
1567
1571
  data-postcode-lookup-label="Back to UK postcode lookup">
1568
1572
 
1569
1573
  <p class="hint pb-2 d-block" slot="hint">Unsure of the postcode? Check with the <a href="https://www.royalmail.com/find-a-postcode" target="_blank"><i class="fa-regular fa-arrow-up-right-from-square"></i>Royal Mail address finder</a></p>
@@ -1600,7 +1604,7 @@ class iamSTDAddressLookup extends HTMLElement {
1600
1604
  <option></option>
1601
1605
  ${countiesString}
1602
1606
  </select></label>
1603
- <label>Postcode${this.hasAttribute('data-show-required') ? '*' : ''} <input name="postcode" type="text" data-required data-readonly maxlength="8" ${this.hasAttribute('data-required') ? ' required' : ''}/></label>
1607
+ <label>Postcode${this.hasAttribute('data-show-required') ? '*' : ''} <input name="postcode" type="text" required data-required data-readonly maxlength="8" ${this.hasAttribute('data-required') ? ' required' : ''}/></label>
1604
1608
  <label>Country${this.hasAttribute('data-show-required') && this.hasAttribute('data-country-required') ? '*' : (!this.hasAttribute('data-show-required') && !this.hasAttribute('data-county-required') ? ' (optional)' : '')}
1605
1609
  <select name="region" data-readonly ${this.hasAttribute('data-country-required') ? 'data-required' : ''}>
1606
1610
  <option value=""></option>
@@ -1749,8 +1753,6 @@ class iamSTDAddressLookup extends HTMLElement {
1749
1753
  }
1750
1754
  });
1751
1755
 
1752
-
1753
-
1754
1756
  }
1755
1757
  }
1756
1758