@iamproperty/components 7.5.1--beta6 → 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 (187) 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.min.js +4 -4
  93. package/assets/js/components/nav/nav.component.min.js +5 -5
  94. package/assets/js/components/nav/nav.component.min.js.map +1 -1
  95. package/assets/js/components/notification/notification.component.min.js +1 -1
  96. package/assets/js/components/pagination/pagination.component.min.js +3 -3
  97. package/assets/js/components/password/password.component.js +93 -0
  98. package/assets/js/components/password/password.component.min.js +17 -0
  99. package/assets/js/components/password/password.component.min.js.map +1 -0
  100. package/assets/js/components/rank/rank.component.min.js +1 -1
  101. package/assets/js/components/rankings/rankings.component.min.js +1 -1
  102. package/assets/js/components/record-card/record-card.component.min.js +4 -4
  103. package/assets/js/components/record-card/record-card.component.min.js.map +1 -1
  104. package/assets/js/components/search/search.component.min.js +1 -1
  105. package/assets/js/components/slider/slider.component.min.js +3 -3
  106. package/assets/js/components/split-button/split-button.component.min.js +1 -1
  107. package/assets/js/components/std-address-lookup/std-address-lookup.component.js +2 -0
  108. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js +18 -8
  109. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js.map +1 -1
  110. package/assets/js/components/table/table.component.min.js +3 -3
  111. package/assets/js/components/table/table.component.min.js.map +1 -1
  112. package/assets/js/components/table-ajax/table-ajax.component.min.js +4 -4
  113. package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -1
  114. package/assets/js/components/table-basic/table-basic.component.min.js +1 -1
  115. package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -1
  116. package/assets/js/components/table-no-submit/table-no-submit.component.min.js +1 -1
  117. package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -1
  118. package/assets/js/components/table-submit/table-submit.component.min.js +1 -1
  119. package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -1
  120. package/assets/js/components/tabs/tabs.component.min.js +2 -2
  121. package/assets/js/components/video-card/video-card.component.min.js +4 -4
  122. package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
  123. package/assets/js/components/word-count/word-count.component.min.js +1 -1
  124. package/assets/js/modules/applied-filters.js +78 -61
  125. package/assets/js/modules/card.module.js +6 -1
  126. package/assets/js/modules/dialogs.js +6 -2
  127. package/assets/js/modules/password.js +72 -0
  128. package/assets/js/modules/table.js +10 -6
  129. package/assets/js/scripts.bundle.js +2 -3
  130. package/assets/js/scripts.bundle.js.map +1 -1
  131. package/assets/js/scripts.bundle.min.js +2 -2
  132. package/assets/js/scripts.bundle.min.js.map +1 -1
  133. package/assets/js/scripts.js +0 -2
  134. package/assets/sass/_components.scss +2 -0
  135. package/assets/sass/_elements.scss +2 -0
  136. package/assets/sass/components/actionbar.component.scss +1 -0
  137. package/assets/sass/components/address-lookup.component.scss +20 -0
  138. package/assets/sass/components/applied-filters.scss +10 -14
  139. package/assets/sass/components/input-range.component.scss +38 -0
  140. package/assets/sass/components/input.component.scss +102 -0
  141. package/assets/sass/components/modal.component.scss +269 -0
  142. package/assets/sass/components/multi-step-modal.component.scss +255 -0
  143. package/assets/sass/components/multi-step-modal.global.scss +92 -0
  144. package/assets/sass/components/password.component.scss +60 -0
  145. package/assets/sass/components/tabs.config.scss +2 -2
  146. package/assets/sass/elements/badge-tag.scss +0 -1
  147. package/assets/sass/elements/details.scss +12 -7
  148. package/assets/sass/elements/dialog.scss +46 -5
  149. package/assets/sass/elements/forms.scss +41 -177
  150. package/assets/sass/elements/hr.scss +1 -1
  151. package/assets/sass/elements/modal.scss +19 -21
  152. package/assets/sass/elements/prefix.scss +115 -0
  153. package/assets/ts/components/accordion/accordion.component.ts +1 -1
  154. package/assets/ts/components/actionbar/actionbar.component.ts +3 -10
  155. package/assets/ts/components/address-lookup/address-lookup.component.ts +60 -0
  156. package/assets/ts/components/applied-filters/applied-filters.component.ts +0 -2
  157. package/assets/ts/components/filter-card/filter-card.component.ts +27 -0
  158. package/assets/ts/components/input/input.component.ts +168 -0
  159. package/assets/ts/components/input-range/input-range.component.ts +78 -0
  160. package/assets/ts/components/modal/modal.component.ts +188 -0
  161. package/assets/ts/components/multi-step-modal/multi-step-modal.component.ts +304 -0
  162. package/assets/ts/components/password/password.component.ts +118 -0
  163. package/assets/ts/components/std-address-lookup/std-address-lookup.component.ts +2 -1
  164. package/assets/ts/modules/applied-filters.ts +107 -71
  165. package/assets/ts/modules/card.module.ts +9 -4
  166. package/assets/ts/modules/dialogs.ts +6 -2
  167. package/assets/ts/modules/password.ts +82 -0
  168. package/assets/ts/modules/table.ts +13 -6
  169. package/assets/ts/scripts.ts +2 -2
  170. package/dist/components.es.js +641 -959
  171. package/dist/components.umd.js +275 -182
  172. package/package.json +2 -2
  173. package/src/components/Input/Input.vue +19 -363
  174. package/src/components/InputRange/InputRange.vue +22 -0
  175. package/src/components/Modal/Modal.vue +22 -0
  176. package/src/components/MultiStepModal/MultiStepModal.vue +23 -0
  177. package/src/components/{PasswordIndicator/PasswordIndicator.vue → Password/Password.vue} +23 -23
  178. package/assets/js/components/password-indicator/password-indicator.component.js +0 -19
  179. package/assets/js/components/password-indicator/password-indicator.component.min.js +0 -7
  180. package/assets/js/components/password-indicator/password-indicator.component.min.js.map +0 -1
  181. package/assets/js/modules/form.js +0 -125
  182. package/assets/js/modules/inputs.js +0 -151
  183. package/assets/js/modules/password-indicator.js +0 -21
  184. package/assets/ts/components/password-indicator/password-indicator.component.ts +0 -24
  185. package/assets/ts/modules/form.ts +0 -166
  186. package/assets/ts/modules/inputs.ts +0 -181
  187. 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;
@@ -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;
@@ -1566,6 +1566,8 @@ class iamSTDAddressLookup extends HTMLElement {
1566
1566
  ${this.hasAttribute('data-error-msg') ? `data-error-msg='${this.getAttribute('data-error-msg')}'` : ''}
1567
1567
  ${this.hasAttribute('data-use-default') ? `data-use-default` : ''}
1568
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')}'` : ''}
1569
1571
  data-postcode-lookup-label="Back to UK postcode lookup">
1570
1572
 
1571
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>
@@ -1751,7 +1753,6 @@ class iamSTDAddressLookup extends HTMLElement {
1751
1753
  }
1752
1754
  });
1753
1755
 
1754
-
1755
1756
  }
1756
1757
  }
1757
1758