@iamproperty/components 7.5.1--beta6 → 7.5.1--beta8
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.js +0 -1
- package/assets/js/components/pagination/pagination.component.min.js +4 -4
- package/assets/js/components/pagination/pagination.component.min.js.map +1 -1
- 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 +4 -4
- 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 +2 -2
- 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 +2 -2
- 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 +80 -62
- 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 +103 -32
- 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/pagination/pagination.component.ts +0 -2
- 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 +110 -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 +102 -12
- 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,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;
|
|
@@ -201,8 +201,6 @@ class iamPagination extends HTMLElement {
|
|
|
201
201
|
if (oldVal && oldVal != newVal) {
|
|
202
202
|
this.setup();
|
|
203
203
|
|
|
204
|
-
console.log(newVal);
|
|
205
|
-
|
|
206
204
|
// Dispact the event for other components to use as triggers
|
|
207
205
|
this.dispatchEvent(new CustomEvent('update-page', { detail: { page: newVal } }));
|
|
208
206
|
}
|
|
@@ -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
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
function createAppliedFilters(container, filters): void {
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const dialog = container.closest('dialog');
|
|
4
|
+
|
|
5
|
+
const addFilterButton = (filters, input, setFilter = false): void | boolean => {
|
|
3
6
|
let shouldRemoveFilter = false;
|
|
4
7
|
let inputName = input.getAttribute('name');
|
|
5
8
|
|
|
@@ -26,7 +29,7 @@ function createAppliedFilters(container, filters): void {
|
|
|
26
29
|
filter.classList.add('filter');
|
|
27
30
|
filter.classList.add('tag');
|
|
28
31
|
|
|
29
|
-
if (
|
|
32
|
+
if (!setFilter) filter.classList.add('tag--not-set');
|
|
30
33
|
|
|
31
34
|
filter.setAttribute('data-name', inputName);
|
|
32
35
|
|
|
@@ -55,7 +58,7 @@ function createAppliedFilters(container, filters): void {
|
|
|
55
58
|
childFilter.classList.add('filter');
|
|
56
59
|
childFilter.classList.add('tag');
|
|
57
60
|
|
|
58
|
-
if (
|
|
61
|
+
if (!setFilter) filter.classList.add('tag--not-set');
|
|
59
62
|
|
|
60
63
|
childFilter.setAttribute('data-name', name);
|
|
61
64
|
childFilter.innerHTML = filterText.replace('$value', element.value);
|
|
@@ -82,107 +85,143 @@ function createAppliedFilters(container, filters): void {
|
|
|
82
85
|
parentFilter.classList.add('filter');
|
|
83
86
|
parentFilter.classList.add('tag');
|
|
84
87
|
|
|
85
|
-
if (
|
|
88
|
+
if (!setFilter) filter.classList.add('tag--not-set');
|
|
86
89
|
|
|
87
90
|
parentFilter.setAttribute('data-name', inputName);
|
|
88
91
|
parentFilter.innerHTML = newFilterText;
|
|
89
92
|
filters.appendChild(parentFilter);
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// check for inputs on load
|
|
95
|
-
Array.from(
|
|
96
|
-
container.querySelectorAll('input[type="checkbox"]:checked, input:not([type="checkbox"]):not([type="radio"])')
|
|
97
|
-
).forEach((input) => {
|
|
98
|
-
addFilterButton(filters, input, false);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
const dialog = container.closest('dialog');
|
|
95
|
+
};
|
|
102
96
|
|
|
103
|
-
|
|
104
|
-
const observer = new MutationObserver(function (event) {
|
|
105
|
-
if (event[0].attributeName == 'open') {
|
|
106
|
-
Array.from(
|
|
107
|
-
container.querySelectorAll('input[type="checkbox"]:checked, input:not([type="checkbox"]):not([type="radio"])')
|
|
108
|
-
).forEach((input) => {
|
|
109
|
-
addFilterButton(filters, input, false);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
});
|
|
97
|
+
const checkForChecked = (setFilter = false) => {
|
|
113
98
|
|
|
114
|
-
observer.observe(dialog, { attributes: true });
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
container.addEventListener('tags-set', function () {
|
|
118
99
|
filters.innerHTML = '';
|
|
119
100
|
Array.from(
|
|
120
|
-
container.querySelectorAll('input[type="checkbox"]:checked, input:not([type="checkbox"]
|
|
101
|
+
container.querySelectorAll('input:is([type="checkbox"],[type="radio"]):checked, input:not([type="checkbox"], [type="radio"])')
|
|
121
102
|
).forEach((input) => {
|
|
122
|
-
addFilterButton(filters, input,
|
|
103
|
+
addFilterButton(filters, input, setFilter);
|
|
123
104
|
});
|
|
124
|
-
}
|
|
105
|
+
};
|
|
106
|
+
// Check for which inputs have been set, setting true sets the filter as set (blue)
|
|
107
|
+
checkForChecked(true);
|
|
125
108
|
|
|
126
|
-
//
|
|
127
|
-
Array.from(
|
|
128
|
-
container.querySelectorAll('input[type="checkbox"]:checked, input:not([type="checkbox"]):not([type="radio"])')
|
|
129
|
-
).forEach((input) => {
|
|
130
|
-
input.addEventListener('change', function (event) {
|
|
131
|
-
if (!container.hasAttribute('data-keep-same')) addFilterButton(filters, input);
|
|
109
|
+
// Create the main event listener for the component watching for inputs to change
|
|
132
110
|
|
|
133
|
-
|
|
111
|
+
Array.from(container.querySelectorAll('input[data-filter-text]')).forEach((input) => {
|
|
112
|
+
|
|
113
|
+
input.addEventListener('change', function (event) {
|
|
114
|
+
|
|
115
|
+
const setFilter = container.closest('dialog') ? false : true;
|
|
116
|
+
|
|
117
|
+
if (!container.hasAttribute('data-keep-same') && !container.querySelector('dialog'))
|
|
118
|
+
addFilterButton(filters, input, setFilter);
|
|
119
|
+
|
|
120
|
+
if(setFilter){
|
|
121
|
+
|
|
122
|
+
const event = new CustomEvent('update');
|
|
123
|
+
container.parentElement.closest('iam-applied-filters')?.dispatchEvent(event);
|
|
124
|
+
}
|
|
134
125
|
});
|
|
135
126
|
});
|
|
136
127
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
128
|
+
|
|
129
|
+
const filterClicked = (filter) => {
|
|
130
|
+
const names = filter.getAttribute('data-name').split(',');
|
|
131
|
+
|
|
132
|
+
for (let t = 0; t < names.length; t++) {
|
|
133
|
+
const name = names[t];
|
|
134
|
+
let selector = `[name="${name}"]`;
|
|
135
|
+
|
|
136
|
+
if (name.match(/\[(.*)\]/)) {
|
|
137
|
+
//const newName = name.replace(/\[(.*)\]/, `[]`);
|
|
138
|
+
const value = name.replace(/.*\[(.*)\]/, `$1`);
|
|
139
|
+
selector = `[value="${value}"]`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const inputs = container.querySelectorAll(selector);
|
|
143
|
+
|
|
144
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
145
|
+
const input = inputs[i];
|
|
146
|
+
|
|
147
|
+
if (input.getAttribute('type') != 'radio' && input.getAttribute('type') != 'checkbox') {
|
|
148
|
+
input.value = '';
|
|
149
|
+
} else {
|
|
150
|
+
input.checked = false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const changeEvent = new CustomEvent('change');
|
|
154
|
+
input?.dispatchEvent(changeEvent);
|
|
155
|
+
}
|
|
142
156
|
}
|
|
143
|
-
|
|
157
|
+
|
|
158
|
+
filter.remove();
|
|
159
|
+
checkForChecked();
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
144
165
|
|
|
145
166
|
filters.addEventListener(
|
|
146
167
|
'click',
|
|
147
168
|
function (event) {
|
|
148
169
|
if (event && event.target instanceof HTMLElement && event.target.closest('.filter')) {
|
|
149
170
|
const filter = event.target.closest('.filter');
|
|
150
|
-
const
|
|
171
|
+
const filterName = filter.getAttribute('data-name');
|
|
151
172
|
|
|
152
|
-
|
|
153
|
-
const name = names[t];
|
|
154
|
-
let selector = `[name="${name}"]`;
|
|
173
|
+
filterClicked(filter);
|
|
155
174
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
175
|
+
// If you clicked on the filter on the parent component we want to tell the child component which filter to copy
|
|
176
|
+
if(container.querySelector('dialog iam-applied-filters')) {
|
|
177
|
+
const event = new CustomEvent('filter',{'detail':filterName });
|
|
178
|
+
container.querySelector('dialog iam-applied-filters').dispatchEvent(event);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
false
|
|
183
|
+
);
|
|
161
184
|
|
|
162
|
-
|
|
185
|
+
// Listen for
|
|
186
|
+
container.addEventListener('filter', (e) => {
|
|
163
187
|
|
|
164
|
-
|
|
165
|
-
const input = inputs[i];
|
|
188
|
+
const filter = container.shadowRoot.querySelector(`[data-name="${e.detail}"]`);
|
|
166
189
|
|
|
167
|
-
|
|
168
|
-
|
|
190
|
+
filterClicked(filter);
|
|
191
|
+
});
|
|
169
192
|
|
|
170
|
-
|
|
171
|
-
if (!container.hasAttribute('data-nosubmit')) input.closest('form').dispatchEvent(event);
|
|
172
|
-
} else {
|
|
173
|
-
input.checked = false;
|
|
193
|
+
container.addEventListener('set-filters', (e) => {
|
|
174
194
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
195
|
+
checkForChecked(true);
|
|
196
|
+
});
|
|
180
197
|
|
|
181
|
-
|
|
198
|
+
if(dialog){
|
|
199
|
+
// Force the filters inside of the dialog to effect the filters above
|
|
200
|
+
container.querySelector('.btn-primary')?.addEventListener('click', (e) => {
|
|
201
|
+
|
|
202
|
+
const event = new CustomEvent('update');
|
|
203
|
+
|
|
204
|
+
if(container.parentElement.closest('iam-applied-filters'))
|
|
205
|
+
container.parentElement.closest('iam-applied-filters').dispatchEvent(event);
|
|
206
|
+
|
|
207
|
+
if(container.parentElement && container.parentElement.closest('iam-applied-filters') && !container.parentElement.closest('iam-applied-filters').closest('dialog')){
|
|
208
|
+
|
|
209
|
+
const event = new CustomEvent('set-filters');
|
|
210
|
+
container.parentElement.closest('iam-applied-filters').dispatchEvent(event);
|
|
182
211
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
checkForChecked(true);
|
|
215
|
+
|
|
216
|
+
if(!container.querySelector('.btn-primary').hasAttribute('command')){
|
|
217
|
+
|
|
218
|
+
dialog.close();
|
|
219
|
+
const event = new Event('close');
|
|
220
|
+
dialog.dispatchEvent(event);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
});
|
|
224
|
+
}
|
|
186
225
|
}
|
|
187
226
|
|
|
188
227
|
export default createAppliedFilters;
|