@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.
- package/assets/css/components/actionbar.component.css +1 -1
- package/assets/css/components/actionbar.component.css.map +1 -1
- package/assets/css/components/address-lookup.component.css +1 -1
- package/assets/css/components/address-lookup.component.css.map +1 -1
- package/assets/css/components/applied-filters.css +1 -1
- package/assets/css/components/applied-filters.css.map +1 -1
- package/assets/css/components/calendar.component.css +1 -1
- package/assets/css/components/calendar.component.css.map +1 -1
- package/assets/css/components/card.component.css +1 -1
- package/assets/css/components/card.component.css.map +1 -1
- package/assets/css/components/fileupload.css +1 -1
- package/assets/css/components/fileupload.css.map +1 -1
- package/assets/css/components/input-range.component.css +1 -0
- package/assets/css/components/input-range.component.css.map +1 -0
- package/assets/css/components/input.component.css +1 -0
- package/assets/css/components/input.component.css.map +1 -0
- package/assets/css/components/modal.component.css +1 -0
- package/assets/css/components/modal.component.css.map +1 -0
- package/assets/css/components/multi-step-modal.component.css +1 -0
- package/assets/css/components/multi-step-modal.component.css.map +1 -0
- package/assets/css/components/multi-step-modal.global.css +1 -0
- package/assets/css/components/multi-step-modal.global.css.map +1 -0
- package/assets/css/components/multiselect.css +1 -1
- package/assets/css/components/multiselect.css.map +1 -1
- package/assets/css/components/nav.component.css +1 -1
- package/assets/css/components/nav.component.css.map +1 -1
- package/assets/css/components/pagination.css +1 -1
- package/assets/css/components/pagination.css.map +1 -1
- package/assets/css/components/password.component.css +1 -0
- package/assets/css/components/password.component.css.map +1 -0
- package/assets/css/components/slider.css +1 -1
- package/assets/css/components/slider.css.map +1 -1
- package/assets/css/components/tabs.component.css +1 -1
- package/assets/css/components/tabs.component.css.map +1 -1
- package/assets/css/components/tabs.config.css +1 -1
- package/assets/css/components/tabs.config.css.map +1 -1
- package/assets/css/core.min.css +1 -1
- package/assets/css/core.min.css.map +1 -1
- package/assets/css/mobile-core.min.css +1 -1
- package/assets/css/mobile-core.min.css.map +1 -1
- package/assets/css/mobile.min.css +1 -1
- package/assets/css/mobile.min.css.map +1 -1
- package/assets/css/style.min.css +1 -1
- package/assets/css/style.min.css.map +1 -1
- package/assets/js/components/accordion/accordion.component.js +1 -1
- package/assets/js/components/accordion/accordion.component.min.js +3 -3
- package/assets/js/components/accordion/accordion.component.min.js.map +1 -1
- package/assets/js/components/actionbar/actionbar.component.js +2 -4
- package/assets/js/components/actionbar/actionbar.component.min.js +4 -4
- package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
- package/assets/js/components/address-lookup/address-lookup.component.js +45 -0
- package/assets/js/components/address-lookup/address-lookup.component.min.js +12 -4
- package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
- package/assets/js/components/advanced-select/advanced-select.component.min.js +1 -1
- package/assets/js/components/applied-filters/applied-filters.component.js +0 -2
- package/assets/js/components/applied-filters/applied-filters.component.min.js +5 -7
- package/assets/js/components/applied-filters/applied-filters.component.min.js.map +1 -1
- package/assets/js/components/barchart/barchart.component.min.js +1 -1
- package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
- package/assets/js/components/calendar/calendar.component.min.js +5 -5
- package/assets/js/components/card/card.component.min.js +8 -8
- package/assets/js/components/card/card.component.min.js.map +1 -1
- package/assets/js/components/carousel/carousel.component.min.js +1 -1
- package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
- package/assets/js/components/content/content.component.min.js +1 -1
- package/assets/js/components/darkmode/darkmode.component.min.js +1 -1
- package/assets/js/components/doughnutchart/doughnutchart.component.min.js +1 -1
- package/assets/js/components/fileupload/fileupload.component.min.js +4 -4
- package/assets/js/components/filter-card/filter-card.component.js +19 -0
- package/assets/js/components/filter-card/filter-card.component.min.js +4 -4
- package/assets/js/components/filter-card/filter-card.component.min.js.map +1 -1
- package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
- package/assets/js/components/header/header.component.min.js +1 -1
- package/assets/js/components/inline-edit/inline-edit.component.min.js +1 -1
- package/assets/js/components/input/input.component.js +128 -0
- package/assets/js/components/input/input.component.min.js +16 -0
- package/assets/js/components/input/input.component.min.js.map +1 -0
- package/assets/js/components/input-range/input-range.component.js +62 -0
- package/assets/js/components/input-range/input-range.component.min.js +14 -0
- package/assets/js/components/input-range/input-range.component.min.js.map +1 -0
- package/assets/js/components/marketing/marketing.component.min.js +1 -1
- package/assets/js/components/menu/menu.component.min.js +1 -1
- package/assets/js/components/milestone/milestone.component.min.js +1 -1
- package/assets/js/components/milestone-group/milestone-group.component.min.js +1 -1
- package/assets/js/components/modal/modal.component.js +141 -0
- package/assets/js/components/modal/modal.component.min.js +28 -0
- package/assets/js/components/modal/modal.component.min.js.map +1 -0
- package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
- package/assets/js/components/multi-step-modal/multi-step-modal.component.js +233 -0
- package/assets/js/components/multi-step-modal/multi-step-modal.component.min.js +17 -0
- package/assets/js/components/multi-step-modal/multi-step-modal.component.min.js.map +1 -0
- package/assets/js/components/multiselect/multiselect.component.min.js +4 -4
- package/assets/js/components/nav/nav.component.min.js +5 -5
- package/assets/js/components/nav/nav.component.min.js.map +1 -1
- package/assets/js/components/notification/notification.component.min.js +1 -1
- package/assets/js/components/pagination/pagination.component.min.js +3 -3
- package/assets/js/components/password/password.component.js +93 -0
- package/assets/js/components/password/password.component.min.js +17 -0
- package/assets/js/components/password/password.component.min.js.map +1 -0
- package/assets/js/components/rank/rank.component.min.js +1 -1
- package/assets/js/components/rankings/rankings.component.min.js +1 -1
- package/assets/js/components/record-card/record-card.component.min.js +4 -4
- package/assets/js/components/record-card/record-card.component.min.js.map +1 -1
- package/assets/js/components/search/search.component.min.js +1 -1
- package/assets/js/components/slider/slider.component.min.js +3 -3
- package/assets/js/components/split-button/split-button.component.min.js +1 -1
- package/assets/js/components/std-address-lookup/std-address-lookup.component.js +2 -0
- package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js +18 -8
- package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js.map +1 -1
- package/assets/js/components/table/table.component.min.js +3 -3
- package/assets/js/components/table/table.component.min.js.map +1 -1
- package/assets/js/components/table-ajax/table-ajax.component.min.js +4 -4
- package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -1
- package/assets/js/components/table-basic/table-basic.component.min.js +1 -1
- package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -1
- package/assets/js/components/table-no-submit/table-no-submit.component.min.js +1 -1
- package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -1
- package/assets/js/components/table-submit/table-submit.component.min.js +1 -1
- package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -1
- package/assets/js/components/tabs/tabs.component.min.js +2 -2
- package/assets/js/components/video-card/video-card.component.min.js +4 -4
- package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
- package/assets/js/components/word-count/word-count.component.min.js +1 -1
- package/assets/js/modules/applied-filters.js +78 -61
- package/assets/js/modules/card.module.js +6 -1
- package/assets/js/modules/dialogs.js +6 -2
- package/assets/js/modules/password.js +72 -0
- package/assets/js/modules/table.js +10 -6
- package/assets/js/scripts.bundle.js +2 -3
- package/assets/js/scripts.bundle.js.map +1 -1
- package/assets/js/scripts.bundle.min.js +2 -2
- package/assets/js/scripts.bundle.min.js.map +1 -1
- package/assets/js/scripts.js +0 -2
- package/assets/sass/_components.scss +2 -0
- package/assets/sass/_elements.scss +2 -0
- package/assets/sass/components/actionbar.component.scss +1 -0
- package/assets/sass/components/address-lookup.component.scss +20 -0
- package/assets/sass/components/applied-filters.scss +10 -14
- package/assets/sass/components/input-range.component.scss +38 -0
- package/assets/sass/components/input.component.scss +102 -0
- package/assets/sass/components/modal.component.scss +269 -0
- package/assets/sass/components/multi-step-modal.component.scss +255 -0
- package/assets/sass/components/multi-step-modal.global.scss +92 -0
- package/assets/sass/components/password.component.scss +60 -0
- package/assets/sass/components/tabs.config.scss +2 -2
- package/assets/sass/elements/badge-tag.scss +0 -1
- package/assets/sass/elements/details.scss +12 -7
- package/assets/sass/elements/dialog.scss +46 -5
- package/assets/sass/elements/forms.scss +41 -177
- package/assets/sass/elements/hr.scss +1 -1
- package/assets/sass/elements/modal.scss +19 -21
- package/assets/sass/elements/prefix.scss +115 -0
- package/assets/ts/components/accordion/accordion.component.ts +1 -1
- package/assets/ts/components/actionbar/actionbar.component.ts +3 -10
- package/assets/ts/components/address-lookup/address-lookup.component.ts +60 -0
- package/assets/ts/components/applied-filters/applied-filters.component.ts +0 -2
- package/assets/ts/components/filter-card/filter-card.component.ts +27 -0
- package/assets/ts/components/input/input.component.ts +168 -0
- package/assets/ts/components/input-range/input-range.component.ts +78 -0
- package/assets/ts/components/modal/modal.component.ts +188 -0
- package/assets/ts/components/multi-step-modal/multi-step-modal.component.ts +304 -0
- package/assets/ts/components/password/password.component.ts +118 -0
- package/assets/ts/components/std-address-lookup/std-address-lookup.component.ts +2 -1
- package/assets/ts/modules/applied-filters.ts +107 -71
- package/assets/ts/modules/card.module.ts +9 -4
- package/assets/ts/modules/dialogs.ts +6 -2
- package/assets/ts/modules/password.ts +82 -0
- package/assets/ts/modules/table.ts +13 -6
- package/assets/ts/scripts.ts +2 -2
- package/dist/components.es.js +641 -959
- package/dist/components.umd.js +275 -182
- package/package.json +2 -2
- package/src/components/Input/Input.vue +19 -363
- package/src/components/InputRange/InputRange.vue +22 -0
- package/src/components/Modal/Modal.vue +22 -0
- package/src/components/MultiStepModal/MultiStepModal.vue +23 -0
- package/src/components/{PasswordIndicator/PasswordIndicator.vue → Password/Password.vue} +23 -23
- package/assets/js/components/password-indicator/password-indicator.component.js +0 -19
- package/assets/js/components/password-indicator/password-indicator.component.min.js +0 -7
- package/assets/js/components/password-indicator/password-indicator.component.min.js.map +0 -1
- package/assets/js/modules/form.js +0 -125
- package/assets/js/modules/inputs.js +0 -151
- package/assets/js/modules/password-indicator.js +0 -21
- package/assets/ts/components/password-indicator/password-indicator.component.ts +0 -24
- package/assets/ts/modules/form.ts +0 -166
- package/assets/ts/modules/inputs.ts +0 -181
- 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
|
|